# Module Service - App Database
## Overview
The App Database Service provides specialized database functionality for distributed applications within the Cellframe SDK. This service offers persistent data storage, query capabilities, and database management specifically designed for decentralized applications running on the Cellframe network.
*Based on: `dap_chain_net_srv_app_db.h`, `dap_chain_net_srv_app_db.c`*
## Document Structure
- [[#Overview|Overview]]
- [[#Database Structures|Database Structures]]
- [[#Database Context|Database Context - Database connection]]
- [[#Query Structure|Query Structure - Query parameters]]
- [[#Database Functions|Database Functions]]
- [[#Database Management|Database Management Functions]]
- [[#Query Operations|Query Operations Functions]]
- [[#Typical Examples|Typical Examples]]
## Database Structures
### Database Context Structure
Structure for managing database connections and context.
```c
typedef struct dap_chain_net_srv_app_db_context {
char db_name[64]; // Database name
char app_name[64]; // Associated application name
dap_chain_addr_t owner_addr; // Database owner address
uint64_t created_timestamp; // Creation timestamp
uint64_t last_access_timestamp; // Last access timestamp
bool is_active; // Database status
void *db_handle; // Internal database handle
pthread_mutex_t access_mutex; // Thread-safe access
} dap_chain_net_srv_app_db_context_t;
```
### Query Structure
Structure for database query operations.
```c
typedef struct dap_chain_net_srv_app_db_query {
char query_string[2048]; // SQL query string
uint32_t query_type; // Query type (SELECT, INSERT, etc.)
void *parameters; // Query parameters
size_t param_count; // Number of parameters
uint64_t timestamp; // Query timestamp
uint32_t timeout_ms; // Query timeout in milliseconds
} dap_chain_net_srv_app_db_query_t;
```
### Query Result Structure
Structure for query result data.
```c
typedef struct dap_chain_net_srv_app_db_result {
uint32_t row_count; // Number of result rows
uint32_t column_count; // Number of columns
char **column_names; // Column name array
void **data; // Result data array
size_t data_size; // Total data size
bool success; // Query success status
char error_message[256]; // Error message if failed
} dap_chain_net_srv_app_db_result_t;
```
## Database Functions
### Database Management
#### `dap_chain_net_srv_app_db_create()`
Creates a new database for an application.
```c
int dap_chain_net_srv_app_db_create(
dap_chain_net_t *a_net,
const char *a_app_name,
const char *a_db_name,
dap_chain_addr_t *a_owner_addr
);
```
**Parameters:**
- `a_net` (dap_chain_net_t *) - Network context
- `a_app_name` (const char *) - Application name
- `a_db_name` (const char *) - Database name
- `a_owner_addr` (dap_chain_addr_t *) - Owner address
**Returns:**
- `0` - Database created successfully
- `-1` - Invalid parameters
- `-2` - Database already exists
- `-3` - Creation failed
#### `dap_chain_net_srv_app_db_connect()`
Connects to an existing database.
```c
dap_chain_net_srv_app_db_context_t* dap_chain_net_srv_app_db_connect(
dap_chain_net_t *a_net,
const char *a_app_name,
const char *a_db_name
);
```
**Parameters:**
- `a_net` (dap_chain_net_t *) - Network context
- `a_app_name` (const char *) - Application name
- `a_db_name` (const char *) - Database name
**Returns:**
- Pointer to database context
- `NULL` if connection failed
#### `dap_chain_net_srv_app_db_disconnect()`
Disconnects from a database.
```c
void dap_chain_net_srv_app_db_disconnect(dap_chain_net_srv_app_db_context_t *a_context);
```
**Parameters:**
- `a_context` (dap_chain_net_srv_app_db_context_t *) - Database context
#### `dap_chain_net_srv_app_db_delete()`
Deletes a database and all its data.
```c
int dap_chain_net_srv_app_db_delete(
dap_chain_net_t *a_net,
const char *a_app_name,
const char *a_db_name
);
```
**Parameters:**
- `a_net` (dap_chain_net_t *) - Network context
- `a_app_name` (const char *) - Application name
- `a_db_name` (const char *) - Database name
**Returns:**
- `0` - Database deleted successfully
- `-1` - Database not found
- `-2` - Deletion failed
### Query Operations
#### `dap_chain_net_srv_app_db_execute()`
Executes a database query.
```c
dap_chain_net_srv_app_db_result_t* dap_chain_net_srv_app_db_execute(
dap_chain_net_srv_app_db_context_t *a_context,
dap_chain_net_srv_app_db_query_t *a_query
);
```
**Parameters:**
- `a_context` (dap_chain_net_srv_app_db_context_t *) - Database context
- `a_query` (dap_chain_net_srv_app_db_query_t *) - Query to execute
**Returns:**
- Pointer to query result
- `NULL` if execution failed
#### `dap_chain_net_srv_app_db_execute_simple()`
Executes a simple SQL query string.
```c
dap_chain_net_srv_app_db_result_t* dap_chain_net_srv_app_db_execute_simple(
dap_chain_net_srv_app_db_context_t *a_context,
const char *a_sql
);
```
**Parameters:**
- `a_context` (dap_chain_net_srv_app_db_context_t *) - Database context
- `a_sql` (const char *) - SQL query string
**Returns:**
- Pointer to query result
- `NULL` if execution failed
#### `dap_chain_net_srv_app_db_result_free()`
Frees query result memory.
```c
void dap_chain_net_srv_app_db_result_free(dap_chain_net_srv_app_db_result_t *a_result);
```
**Parameters:**
- `a_result` (dap_chain_net_srv_app_db_result_t *) - Result to free
#### `dap_chain_net_srv_app_db_begin_transaction()`
Begins a database transaction.
```c
int dap_chain_net_srv_app_db_begin_transaction(dap_chain_net_srv_app_db_context_t *a_context);
```
**Parameters:**
- `a_context` (dap_chain_net_srv_app_db_context_t *) - Database context
**Returns:**
- `0` - Transaction started successfully
- Non-zero - Transaction start failed
#### `dap_chain_net_srv_app_db_commit_transaction()`
Commits a database transaction.
```c
int dap_chain_net_srv_app_db_commit_transaction(dap_chain_net_srv_app_db_context_t *a_context);
```
**Parameters:**
- `a_context` (dap_chain_net_srv_app_db_context_t *) - Database context
**Returns:**
- `0` - Transaction committed successfully
- Non-zero - Commit failed
#### `dap_chain_net_srv_app_db_rollback_transaction()`
Rolls back a database transaction.
```c
int dap_chain_net_srv_app_db_rollback_transaction(dap_chain_net_srv_app_db_context_t *a_context);
```
**Parameters:**
- `a_context` (dap_chain_net_srv_app_db_context_t *) - Database context
**Returns:**
- `0` - Transaction rolled back successfully
- Non-zero - Rollback failed
## Typical Examples
### Database Creation and Connection Example
```c
#include <dap_chain_net_srv_app_db.h>
void app_database_creation_example() {
log_it_info("=== App Database Creation Example ===");
// Step 1: Setup network context
dap_chain_net_t *net = dap_chain_net_by_name("backbone");
if (!net) {
log_it_error("✗ Network 'backbone' not found");
return;
}
// Step 2: Define database parameters
const char *app_name = "MyDApp";
const char *db_name = "UserData";
dap_chain_addr_t owner_addr;
// Initialize owner address (example)
if (dap_chain_addr_from_str(&owner_addr, "mJWQjJA4iXQ7HCZkZHgmPFNv9xAA7GV9eMUTjRdBGNBuKVaZZ3qw2k") != 0) {
log_it_error("✗ Invalid owner address format");
return;
}
log_it_info("Database Parameters:");
log_it_info(" Application: %s", app_name);
log_it_info(" Database: %s", db_name);
log_it_info(" Network: %s", net->pub.name);
log_it_info(" Owner: %s", dap_chain_addr_to_str(&owner_addr));
// Step 3: Create database
log_it_info("--- Creating Database ---");
int create_result = dap_chain_net_srv_app_db_create(
net,
app_name,
db_name,
&owner_addr
);
switch (create_result) {
case 0:
log_it_info("✓ Database created successfully");
break;
case -1:
log_it_error("✗ Invalid database parameters");
return;
case -2:
log_it_error("✗ Database already exists");
break;
case -3:
log_it_error("✗ Database creation failed");
return;
default:
log_it_error("✗ Unknown creation error: %d", create_result);
return;
}
// Step 4: Connect to database
log_it_info("--- Connecting to Database ---");
dap_chain_net_srv_app_db_context_t *db_context = dap_chain_net_srv_app_db_connect(
net,
app_name,
db_name
);
if (db_context) {
log_it_info("✓ Database connection established");
log_it_info(" Database: %s", db_context->db_name);
log_it_info(" Application: %s", db_context->app_name);
log_it_info(" Status: %s", db_context->is_active ? "Active" : "Inactive");
log_it_info(" Created: %lu", db_context->created_timestamp);
} else {
log_it_error("✗ Database connection failed");
return;
}
// Step 5: Create initial tables
log_it_info("--- Creating Initial Schema ---");
const char *create_table_sql =
"CREATE TABLE users ("
"id INTEGER PRIMARY KEY AUTOINCREMENT, "
"username VARCHAR(50) NOT NULL UNIQUE, "
"email VARCHAR(100) NOT NULL, "
"created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP"
")";
dap_chain_net_srv_app_db_result_t *create_result_data = dap_chain_net_srv_app_db_execute_simple(
db_context,
create_table_sql
);
if (create_result_data && create_result_data->success) {
log_it_info("✓ Initial table 'users' created successfully");
} else {
log_it_error("✗ Table creation failed: %s",
create_result_data ? create_result_data->error_message : "Unknown error");
}
// Step 6: Cleanup
if (create_result_data) {
dap_chain_net_srv_app_db_result_free(create_result_data);
}
dap_chain_net_srv_app_db_disconnect(db_context);
log_it_info("✓ Database connection closed");
log_it_info("App database creation example completed");
}
```
### Database Operations Example
```c
#include <dap_chain_net_srv_app_db.h>
void app_database_operations_example() {
log_it_info("=== App Database Operations Example ===");
// Step 1: Connect to existing database
dap_chain_net_t *net = dap_chain_net_by_name("backbone");
if (!net) {
log_it_error("✗ Network not found");
return;
}
dap_chain_net_srv_app_db_context_t *db_context = dap_chain_net_srv_app_db_connect(
net, "MyDApp", "UserData"
);
if (!db_context) {
log_it_error("✗ Could not connect to database");
return;
}
log_it_info("✓ Connected to database successfully");
// Step 2: Insert data with transaction
log_it_info("--- Data Insertion with Transaction ---");
int transaction_result = dap_chain_net_srv_app_db_begin_transaction(db_context);
if (transaction_result != 0) {
log_it_error("✗ Failed to begin transaction");
dap_chain_net_srv_app_db_disconnect(db_context);
return;
}
log_it_info("✓ Transaction started");
// Insert multiple users
const char *insert_queries[] = {
"INSERT INTO users (username, email) VALUES ('alice', '
[email protected]')",
"INSERT INTO users (username, email) VALUES ('bob', '
[email protected]')",
"INSERT INTO users (username, email) VALUES ('charlie', '
[email protected]')"
};
bool all_inserts_successful = true;
for (int i = 0; i < 3; i++) {
dap_chain_net_srv_app_db_result_t *insert_result = dap_chain_net_srv_app_db_execute_simple(
db_context,
insert_queries[i]
);
if (insert_result && insert_result->success) {
log_it_info("✓ User %d inserted successfully", i + 1);
} else {
log_it_error("✗ User %d insertion failed: %s", i + 1,
insert_result ? insert_result->error_message : "Unknown error");
all_inserts_successful = false;
}
if (insert_result) {
dap_chain_net_srv_app_db_result_free(insert_result);
}
}
// Commit or rollback transaction
if (all_inserts_successful) {
int commit_result = dap_chain_net_srv_app_db_commit_transaction(db_context);
if (commit_result == 0) {
log_it_info("✓ Transaction committed successfully");
} else {
log_it_error("✗ Transaction commit failed");
}
} else {
int rollback_result = dap_chain_net_srv_app_db_rollback_transaction(db_context);
if (rollback_result == 0) {
log_it_info("✓ Transaction rolled back due to errors");
} else {
log_it_error("✗ Transaction rollback failed");
}
}
// Step 3: Query data
log_it_info("--- Data Query ---");
const char *select_sql = "SELECT id, username, email, created_at FROM users ORDER BY id";
dap_chain_net_srv_app_db_result_t *select_result = dap_chain_net_srv_app_db_execute_simple(
db_context,
select_sql
);
if (select_result && select_result->success) {
log_it_info("✓ Query executed successfully");
log_it_info(" Rows returned: %u", select_result->row_count);
log_it_info(" Columns: %u", select_result->column_count);
// Display column headers
log_it_info("Query Results:");
log_it_info("╭─────┬──────────┬─────────────────────┬─────────────────────╮");
log_it_info("│ ID │ Username │ Email │ Created At │");
log_it_info("├─────┼──────────┼─────────────────────┼─────────────────────┤");
// Display data (simulated - actual implementation would iterate through results)
log_it_info("│ 1 │ alice │
[email protected] │ 2024-01-01 12:00:00 │");
log_it_info("│ 2 │ bob │
[email protected] │ 2024-01-01 12:00:01 │");
log_it_info("│ 3 │ charlie │
[email protected] │ 2024-01-01 12:00:02 │");
log_it_info("╰─────┴──────────┴─────────────────────┴─────────────────────╯");
} else {
log_it_error("✗ Query execution failed: %s",
select_result ? select_result->error_message : "Unknown error");
}
// Step 4: Advanced query with parameters
log_it_info("--- Parameterized Query ---");
dap_chain_net_srv_app_db_query_t parameterized_query = {
.query_string = "SELECT * FROM users WHERE username = ? AND email LIKE ?",
.query_type = 1, // SELECT type
.param_count = 2,
.timeout_ms = 5000
};
// In a real implementation, you would set the parameters here
log_it_info("Parameterized query prepared:");
log_it_info(" SQL: %s", parameterized_query.query_string);
log_it_info(" Parameters: 2 (username, email pattern)");
log_it_info(" Timeout: %u ms", parameterized_query.timeout_ms);
// Step 5: Cleanup
if (select_result) {
dap_chain_net_srv_app_db_result_free(select_result);
}
dap_chain_net_srv_app_db_disconnect(db_context);
log_it_info("✓ Database connection closed");
log_it_info("App database operations example completed");
}
```
---
*See also: [[Modules/Module Service|Module Service]], [[Modules/Module Service - Application|Module Service - Application]], [[ETC/Services Overview|Services Overview]]*