# Database Operations

Zephyr currently supports the following types of database interactions:

* Write.
* Read.
* Update.

On the guest level, there is no auth to handle so this is pretty straightforward as you don't have to grant any special permissions.

## Write

In the Zephyr VM, or better in the Mercury abstraction of the VM implementation, a write operation translates to a SQL insert statement and it is performed by providing a constructed `DatabaseDerive` object to the `EnvClient::put()` function:

<pre class="language-rust"><code class="lang-rust"><strong>#[derive(DatabaseDerive, Clone)]
</strong>#[with_name("test")]
struct TestTable {
    hello: ScVal,
}

#[no_mangle]
pub extern "C" fn on_close() {
    let env = EnvClient::new();
    // define the message
    let table = TestTable {
        hello: message.clone(),
    };
    
    table.put(&#x26;env);
}
</code></pre>

In this case, "table" is a `DatabaseDerive` object and represents a new row in the table.

## Read

Reading means returning an iterator (a vec currently) over `DatabaseDerive` elements, as many as the rows present in the requested table. It is done by simply calling `EnvClient::read()` while inferring the requested table type (which will automatically translate to reading from the corresponding table):

```rust
let rows = env.read::<TestTable>();
for row in rows {
    // ...
}
```

## Update

Updating lets you update a selection of the table by changing some rows with a new given one. You have to specify the conditions under which to change the rows, and the new row as a `DatabaseDerive` element:

```rust
let table = TestTable {
    hello: message1.clone(),
};

// note: message1 is an ScVal
env.update().column_equal_to_xdr("hello", &message).execute(&table)
```

In this snippet, all rows where the `hello` column equals to the `message` ScVal will be updated with the row defined by `table`.
