1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
// When generating docs with either keyvalue or pubsub features disabled, there
// will be broken links in these docs. Instead of failing to generate docs with
// these feaures disabled, we downgrade the `broken_intra_doc_links` lint to a
// warning.
#![cfg_attr(
    all(doc, not(all(feature = "keyvalue", feature = "pubsub"))),
    warn(broken_intra_doc_links)
)]
use actionable::{Action, ResourceName};
use serde::{Deserialize, Serialize};

use crate::schema::{CollectionName, ViewName};

/// Creates a resource name with the database `name`.
#[must_use]
pub fn pliantdb_resource_name<'a>() -> ResourceName<'a> {
    ResourceName::named("pliantdb")
}

/// Creates a resource name with the database `name`.
#[must_use]
pub fn database_resource_name(name: &'_ str) -> ResourceName<'_> {
    pliantdb_resource_name().and(name)
}

/// Creates a resource name for a `collection` within a `database`.
#[must_use]
pub fn collection_resource_name<'a>(
    database: &'a str,
    collection: &'a CollectionName,
) -> ResourceName<'a> {
    database_resource_name(database).and(collection.to_string())
}

/// Creates a resource name for a document `id` within `collection` within `database`.
#[must_use]
pub fn document_resource_name<'a>(
    database: &'a str,
    collection: &'a CollectionName,
    id: u64,
) -> ResourceName<'a> {
    collection_resource_name(database, collection)
        .and("document")
        .and(id)
}

/// Creaets a resource name for a `view` within `database`.
#[must_use]
pub fn view_resource_name<'a>(database: &'a str, view: &'a ViewName) -> ResourceName<'a> {
    database_resource_name(database)
        .and(view.collection.to_string())
        .and("view")
        .and(view.name.as_ref())
}

/// Creates a resource name for `PubSub` `topic` within `database`.
#[must_use]
pub fn pubsub_topic_resource_name<'a>(database: &'a str, topic: &'a str) -> ResourceName<'a> {
    database_resource_name(database).and("pubsub").and(topic)
}

/// Creates a resource name for `key` within `namespace` within the key-value store of `database`.
#[must_use]
pub fn kv_key_resource_name<'a>(
    database: &'a str,
    namespace: Option<&'a str>,
    key: &'a str,
) -> ResourceName<'a> {
    database_resource_name(database)
        .and("pubsub")
        .and(namespace.unwrap_or(""))
        .and(key)
}

/// Actions that can be permitted within `PliantDb`.
#[derive(Action, Serialize, Deserialize, Clone, Copy, Debug)]
// Naming by choice despite clippy: without the prefix it would conflict with a common include from the parent module.
#[allow(clippy::module_name_repetitions)]
pub enum PliantAction {
    /// Actions that operate on a server
    Server(ServerAction),
    /// Actions that operate on a specific database.
    Database(DatabaseAction),
}

/// Actions that operate on a server.
#[derive(Action, Serialize, Deserialize, Clone, Copy, Debug)]
pub enum ServerAction {
    /// Permits connecting to the server. Upon negotiating authentication, the
    /// effective permissions of the connected party will be checked for
    /// permissions to `Connect`. If not allowed, the connection will be
    /// terminated. (Not implemented)
    // TODO actually implement Connect checking
    Connect,
    /// Permits [`ServerConnection::list_available_schemas`](crate::connection::ServerConnection::list_available_schemas).
    ListAvailableSchemas,
    /// Permits [`ServerConnection::list_databases`](crate::connection::ServerConnection::list_databases).
    ListDatabases,
    /// Permits [`ServerConnection::create_database`](crate::connection::ServerConnection::create_database).
    CreateDatabase,
    /// Permits [`ServerConnection::delete_database`](crate::connection::ServerConnection::delete_database).
    DeleteDatabase,
}

/// Actions that operate on a specific database.
#[derive(Action, Serialize, Deserialize, Clone, Copy, Debug)]
pub enum DatabaseAction {
    /// Actions that operate on a document.
    Document(DocumentAction),
    /// Actions that operate on a view.
    View(ViewAction),
    /// Actions that operate on transactions.
    Transaction(TransactionAction),
    /// Actions that operate on the `PubSub` system.
    PubSub(PubSubAction),
    /// Actions that operate on the key-value store.
    Kv(KvAction),
}

/// Actions that operate on a document.
#[derive(Action, Serialize, Deserialize, Clone, Copy, Debug)]
pub enum DocumentAction {
    /// Allows document retrieval through
    /// [`Connection::get()`](crate::connection::Connection::get) and
    /// [`Connection::get_multiple()`](crate::connection::Connection::get_multiple).
    /// See [`document_resource_name()`] for the format of document resource
    /// names.
    Get,
    /// Allows inserting a document through
    /// [`Connection::apply_transaction()`](crate::connection::Connection::apply_transaction).
    /// See [`collection_resource_name()`] for the format of collection resource
    /// names.
    Insert,
    /// Allows updating a document through
    /// [`Connection::apply_transaction()`](crate::connection::Connection::apply_transaction).
    /// See [`document_resource_name()`] for the format of document resource
    /// names.
    Update,
    /// Allows deleting a document through
    /// [`Connection::apply_transaction()`](crate::connection::Connection::apply_transaction).
    /// See [`document_resource_name()`] for the format of document resource
    /// names.
    Delete,
}

/// Actions that operate on a view.
#[derive(Action, Serialize, Deserialize, Clone, Copy, Debug)]
pub enum ViewAction {
    /// Allows querying a view with
    /// [`Connection::query()`](crate::connection::Connection::query). See
    /// [`view_resource_name`] for the format of view resource names.
    Query,
    /// Allows reducing a view with
    /// [`Connection::reduce()`](crate::connection::Connection::reduce). See
    /// [`view_resource_name`] for the format of view resource names.
    Reduce,
}

/// Actions that operate on transactions.
#[derive(Action, Serialize, Deserialize, Clone, Copy, Debug)]
pub enum TransactionAction {
    /// Allows listing executed transactions with
    /// [`Connection::list_executed_transactions()`](crate::connection::Connection::list_executed_transactions).
    /// This action is checked against the database's resource name. See
    /// [`database_resource_name()`] for the format of database resource names.
    ListExecuted,
    /// Allows retrieving the last executed transaction id with
    /// [`Connection::last_transaction_id()`](crate::connection::Connection::last_transaction_id).
    /// This action is checked against the database's resource name. See
    /// [`database_resource_name()`] for the format of database resource names.
    GetLastId,
}

/// Actions that operate on the `PubSub` system.
#[derive(Action, Serialize, Deserialize, Clone, Copy, Debug)]
pub enum PubSubAction {
    /// Allows creating a subscriber with
    /// [`PubSub::create_subscriber()`](crate::pubsub::PubSub::create_subscriber).
    /// This action is checked against the database's resource name. See
    /// [`database_resource_name()`] for the format of database resource names.
    CreateSuscriber,
    /// Allows publishing a payload to a `PubSub` topic with
    /// [`PubSub::publish()`](crate::pubsub::PubSub::publish). See
    /// [`pubsub_topic_resource_name()`] for the format of `PubSub` topic
    /// resource names.
    Publish,
    /// Allows subscribing to a `PubSub` topic with
    /// [`PubSub::subscribe_to()`](crate::pubsub::Subscriber::subscribe_to). See
    /// [`pubsub_topic_resource_name()`] for the format of `PubSub` topic
    /// resource names.
    SubscribeTo,
    /// Allows unsubscribing from a `PubSub` topic with
    /// [`PubSub::unsubscribe_from()`](crate::pubsub::Subscriber::unsubscribe_from). See
    /// [`pubsub_topic_resource_name()`] for the format of `PubSub` topic
    /// resource names.
    UnsubscribeFrom,
}

/// Actions that operate on the key-value store.
#[derive(Action, Serialize, Deserialize, Clone, Copy, Debug)]
pub enum KvAction {
    /// Allows executing a key-value store operation with
    /// [`Kv::execute_key_operation()`](crate::kv::Kv::execute_key_operation).
    /// See [`kv_key_resource_name()`] for the format of key resource names.
    ExecuteOperation,
}