Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add reset function to db backend #62

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
153 changes: 153 additions & 0 deletions backend/db/sql-generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -2145,4 +2145,157 @@ backend_iterate(gpointer _iterator, bson_t* metadata, GError** error)
/*something failed very hard*/
return FALSE;
}

static
gboolean
backend_reset(gpointer _batch, GError** error)
{
J_TRACE_FUNCTION(NULL);

JDBType type;
JThreadVariables* thread_variables = NULL;
void* stmt1;
void* stmt2;
JSqlBatch* batch = _batch;
gboolean found1 = FALSE;
gboolean found2 = FALSE;
g_autoptr(GArray) arr_types_out1 = NULL;
g_autoptr(GArray) arr_types_out2 = NULL;
JDBTypeValue value1;
JDBTypeValue value2;
char sql_strbuf[256];
char table_name[128];
g_autoptr(GString) error_string = NULL;

g_return_val_if_fail(_batch != NULL, FALSE);
g_return_val_if_fail(error == NULL || *error == NULL, FALSE);

if (G_UNLIKELY(!(thread_variables = thread_variables_get(error))))
{
goto _error3;
}
if (G_UNLIKELY(!_backend_batch_execute(batch, error)))
{
//no ddl in transaction - most databases wont support that - continue without any open transaction
goto _error3;
}
arr_types_out1 = g_array_new(FALSE, FALSE, sizeof(JDBType));
type = J_DB_TYPE_STRING;
g_array_append_val(arr_types_out1, type);
arr_types_out2 = g_array_new(FALSE, FALSE, sizeof(JDBType));
type = J_DB_TYPE_UINT32;
g_array_append_val(arr_types_out2, type);
do
{
snprintf(sql_strbuf, sizeof(sql_strbuf), sql_get_table_names, batch->namespace);
if (G_UNLIKELY(!j_sql_prepare(thread_variables->sql_backend, sql_strbuf, &stmt1, NULL, arr_types_out1, error)))
{
goto _error3;
}
if (G_UNLIKELY(!j_sql_step(thread_variables->sql_backend, stmt1, &found1, error)))
{
goto _error2;
}
if (!found1)
{
break;
}
value1.val_string = NULL;
if (G_UNLIKELY(!j_sql_column(thread_variables->sql_backend, stmt1, 0, J_DB_TYPE_STRING, &value1, error)))
{
goto _error2;
}
strncpy(table_name, value1.val_string, sizeof(table_name));
if (G_UNLIKELY(!j_sql_reset(thread_variables->sql_backend, stmt1, error)))
{
goto _error2;
}
if (G_UNLIKELY(!j_sql_finalize(thread_variables->sql_backend, stmt1, error)))
{
goto _error3;
}
snprintf(sql_strbuf, sizeof(sql_strbuf), "SELECT COUNT(*) FROM '%s'", table_name);
if (G_UNLIKELY(!j_sql_prepare(thread_variables->sql_backend, sql_strbuf, &stmt2, NULL, arr_types_out2, error)))
{
goto _error3;
}
if (G_UNLIKELY(!j_sql_step(thread_variables->sql_backend, stmt2, &found2, error)))
{
goto _error;
}
if (!found2)
{
g_set_error(error, J_BACKEND_DB_ERROR, 0, "reset %s count not found", table_name);
goto _error;
}
if (G_UNLIKELY(!j_sql_column(thread_variables->sql_backend, stmt2, 0, J_DB_TYPE_UINT32, &value2, error)))
{
goto _error;
}
if (value2.val_uint32 > 0)
{
if (!error_string)
error_string = g_string_new("reset -- ");
g_string_append_printf(error_string, "%s -> %d, ", table_name, value2.val_uint32);
}
if (G_UNLIKELY(!j_sql_reset(thread_variables->sql_backend, stmt2, error)))
{
goto _error;
}
if (G_UNLIKELY(!j_sql_finalize(thread_variables->sql_backend, stmt2, error)))
{
goto _error3;
}
snprintf(sql_strbuf, sizeof(sql_strbuf), "DROP TABLE '%s'", table_name);
if (G_UNLIKELY(!j_sql_exec(thread_variables->sql_backend, sql_strbuf, error)))
{
goto _error3;
}
} while (TRUE);
if (G_UNLIKELY(!j_sql_reset(thread_variables->sql_backend, stmt1, error)))
{
goto _error2;
}
if (G_UNLIKELY(!j_sql_finalize(thread_variables->sql_backend, stmt1, error)))
{
goto _error3;
}
if (error_string)
{
g_set_error(error, J_BACKEND_DB_ERROR, 0, "%s", error_string->str);
goto _error3;
}
if (G_UNLIKELY(!_backend_batch_start(batch, error)))
{
goto _error3;
}
return TRUE;
_error:
if (G_UNLIKELY(!j_sql_finalize(thread_variables->sql_backend, stmt2, NULL)))
{
goto _error2;
}
if (G_UNLIKELY(!_backend_batch_start(batch, NULL)))
{
goto _error;
}
return FALSE;
_error2:
if (G_UNLIKELY(!j_sql_finalize(thread_variables->sql_backend, stmt1, NULL)))
{
goto _error3;
}
if (G_UNLIKELY(!_backend_batch_start(batch, NULL)))
{
goto _error;
}
return FALSE;
_error3:
/*something failed very hard*/
if (G_UNLIKELY(!_backend_batch_start(batch, NULL)))
{
goto _error;
}
return FALSE;
}
#endif
2 changes: 2 additions & 0 deletions backend/db/sqlite.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@

#define sql_autoincrement_string " "
#define sql_last_insert_id_string " SELECT last_insert_rowid() "
#define sql_get_table_names "SELECT name FROM sqlite_master WHERE type='table' AND name LIKE '%s_%%'"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file has conflicts, please fix them.


static gchar* path;

Expand Down Expand Up @@ -418,6 +419,7 @@ static
JBackend sqlite_backend = {
.type = J_BACKEND_TYPE_DB,
.component = J_BACKEND_COMPONENT_SERVER,
.backend_reset = backend_reset,
.db = {
.backend_init = backend_init,
.backend_fini = backend_fini,
Expand Down
18 changes: 18 additions & 0 deletions include/core/jbackend-operation.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ gboolean j_backend_operation_unwrap_db_update (JBackend*, gpointer, JBackendOper
gboolean j_backend_operation_unwrap_db_delete (JBackend*, gpointer, JBackendOperation*);
gboolean j_backend_operation_unwrap_db_query (JBackend*, gpointer, JBackendOperation*);

gboolean j_backend_operation_unwrap_reset(JBackend* backend, gpointer, JBackendOperation*);

gboolean j_backend_operation_to_message (JMessage* message, JBackendOperationParam* data, guint len);
gboolean j_backend_operation_from_message (JMessage* message, JBackendOperationParam* data, guint len);
gboolean j_backend_operation_from_message_static (JMessage* message, JBackendOperationParam* data, guint len);
Expand Down Expand Up @@ -241,6 +243,22 @@ static const JBackendOperation j_backend_operation_db_query = {
},
};

static const JBackendOperation j_backend_operation_reset = {
.backend_func = j_backend_operation_unwrap_reset,
.in_param_count = 1,
.out_param_count = 1,
.in_param = {
{
.type = J_BACKEND_OPERATION_PARAM_TYPE_STR,
},
},
.out_param = {
{
.type = J_BACKEND_OPERATION_PARAM_TYPE_ERROR,
},
},
};

G_END_DECLS

#endif
8 changes: 8 additions & 0 deletions include/core/jbackend.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,13 @@ struct JBackend
JBackendType type;
JBackendComponent component;

/**
* delete everything in the backend
* \param[in] which namespace to delete
* \param[out] how many "things" are deleted within the specified namespace
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are no in and out parameters in the actual function below.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gpointer is an input parameter containing a batch structure, Error is a out parameter, where the error message-string may contain the number of elements which are deleted

*/
gboolean (*backend_reset)(gpointer, GError**);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this not inside one of the unions?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the intention was to have one reset function for all backend types


union
{
struct
Expand Down Expand Up @@ -431,6 +438,7 @@ gboolean j_backend_db_delete (JBackend*, gpointer, gchar const*, bson_t const*,
gboolean j_backend_db_query (JBackend*, gpointer, gchar const*, bson_t const*, gpointer*, GError**);
gboolean j_backend_db_iterate (JBackend*, gpointer, bson_t*, GError**);

gboolean j_backend_reset (JBackend* backend, gpointer, GError**);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above for naming.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the intention was to have one reset function for all backend types

G_END_DECLS

#endif
3 changes: 2 additions & 1 deletion include/core/jmessage.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ enum JMessageType
J_MESSAGE_DB_INSERT,
J_MESSAGE_DB_UPDATE,
J_MESSAGE_DB_DELETE,
J_MESSAGE_DB_QUERY
J_MESSAGE_DB_QUERY,
J_MESSAGE_RESET
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

J_MESSAGE_DB_RESET?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the intention was to have one reset function for all backend types - that is why there is no DB prefix

};

typedef enum JMessageType JMessageType;
Expand Down
2 changes: 2 additions & 0 deletions include/db/jdb-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ gboolean j_db_internal_delete (gchar const* namespace, gchar const* name, bson_t
gboolean j_db_internal_query (gchar const* namespace, gchar const* name, bson_t const* selector, gpointer* iterator, JBatch* batch, GError** error);
gboolean j_db_internal_iterate (gpointer iterator, bson_t* metadata, GError** error);

gboolean j_internal_reset (gchar const* namespace, JBatch* batch, GError** error);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

j_db_internal_reset?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the intention was to have one reset function for all backend types - maybe this should be moved somewhere in the core if it should be available for all backend types


// Client-side additional internal functions
bson_t* j_db_selector_get_bson (JDBSelector* selector);

Expand Down
9 changes: 9 additions & 0 deletions lib/core/jbackend-operation.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@
* @{
**/

gboolean
j_backend_operation_unwrap_reset(JBackend* backend, gpointer batch, JBackendOperation* data)
{
J_TRACE_FUNCTION(NULL);

return j_backend_reset(backend, batch, data->out_param[0].ptr);
}


gboolean
j_backend_operation_unwrap_db_schema_create (JBackend* backend, gpointer batch, JBackendOperation* data)
{
Expand Down
16 changes: 16 additions & 0 deletions lib/core/jbackend.c
Original file line number Diff line number Diff line change
Expand Up @@ -897,6 +897,22 @@ j_backend_db_iterate (JBackend* backend, gpointer iterator, bson_t* metadata, GE
return ret;
}

gboolean
j_backend_reset(JBackend* backend, gpointer batch, GError** error)
{
J_TRACE_FUNCTION(NULL);

g_return_val_if_fail(backend != NULL, FALSE);
g_return_val_if_fail(batch != NULL, FALSE);
g_return_val_if_fail(error == NULL || *error == NULL, FALSE);

if (backend->backend_reset)
{
return backend->backend_reset(batch, error);
}
return TRUE;
}

/**
* @}
**/
30 changes: 30 additions & 0 deletions lib/db/jdb-internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,36 @@ j_backend_db_func_free (gpointer _data)
}
}

static
gboolean
j_reset_exec(JList* operations, JSemantics* semantics)
{
J_TRACE_FUNCTION(NULL);

//FIXME call this on EVERY backend(type)
return j_backend_db_func_exec(operations, semantics, J_MESSAGE_RESET);
}
gboolean
j_internal_reset(gchar const* namespace, JBatch* batch, GError** error)
{
J_TRACE_FUNCTION(NULL);

JOperation* op;
JBackendOperation* data;

data = g_slice_new(JBackendOperation);
memcpy(data, &j_backend_operation_reset, sizeof(JBackendOperation));
data->in_param[0].ptr_const = namespace;
data->out_param[0].ptr_const = error;
op = j_operation_new();
op->key = namespace;
op->data = data;
op->exec_func = j_reset_exec;
op->free_func = j_backend_db_func_free;
j_batch_add(batch, op);
return TRUE;
}

static
gboolean
j_db_schema_create_exec (JList* operations, JSemantics* semantics)
Expand Down
7 changes: 7 additions & 0 deletions server/loop.c
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,13 @@ jd_handle_message (JMessage* message, GSocketConnection* connection, JMemoryChun
j_message_send(reply, connection);
}
break;
case J_MESSAGE_RESET:
if (!message_matched)
{
memcpy(&backend_operation, &j_backend_operation_reset, sizeof(JBackendOperation));
message_matched = TRUE;
}
// fallthrough
case J_MESSAGE_DB_SCHEMA_CREATE:
if (!message_matched)
{
Expand Down