def body_find_by_id(struct: Struct, func: FunctionTemplate): func.add_macro_def( MacroDefinition("QUERY", '"{}"'.format(find_by_id_sql_string(struct)))) func.add_macro_def(MacroDefinition("PARAM_COUNT", "1")) func.add_block('\tif (conn == NULL) {\n\t\tconn = db_init();\n\t}\n') func.add_block("{}* out;".format(struct.typedef_name)) func.add_block(""" SQL_RESULT* res; struct {name} {name}; {name}.{pk_name} = id; struct {name}* {name}T = &{name}; """.format(name=struct.name, pk_name=struct.get_pk().name)) func.add_block(struct.get_col_param_buffer(["id_{}".format(struct.name)])) func.add_block( "res = {}_execute_find(conn, QUERY, param, PARAM_COUNT);".format( struct.name)) func.add_block(struct.col_param_buffer_free(1)) func.add_block("\tif (res->results == NULL) { return NULL; }") func.add_block("""out = res->results->data; if (res->count == 1) {{ free(res->results); free(res); return out; }} else {{ fprintf(stderr, "{name}_execute_find(), failed - multiple results (%d)\\n", res->count); mysql_res_free(&res); return NULL; }}""".format(name=struct.name)) return func
def body_find_all(struct: Struct, func: FunctionTemplate): func.add_macro_def( MacroDefinition("QUERY", '"{}"'.format(find_all_sql_string(struct)))) func.add_macro_def(MacroDefinition("PARAM_COUNT", str(0))) func.add_block("SQL_RESULT* res;") func.add_block("MYSQL_BIND param[1];") func.add_block('\tif (conn == NULL) {\n\t\tconn = db_init();\n\t}\n') func.add_block( "res = {}_execute_find(conn, QUERY, param, PARAM_COUNT);".format( struct.name)) func.add_block("return res;") return func
def body_execute(struct: Struct, func: FunctionTemplate): # func = struct.declaration_execute() func.add_block("/* Generated by body_execute */") func.add_macro_def(MacroDefinition("QUERY_LENGTH", '512')) func.add_block('\tMYSQL_STMT* stmt;\t\nint retval;') func.add_block('\tif (conn == NULL) {\n\t\tconn = db_init();\n\t}\n') func.add_block('\t\nstmt = mysql_stmt_init(conn);') func.add_block( """if ((retval = mysql_stmt_prepare(stmt, query, strnlen(query, QUERY_LENGTH)))) { fprintf(stderr, "mysql_stmt_prepare(), failed\\n"); fprintf(stderr, "%s\\n", mysql_error(conn)); return retval; }""") func.add_block("""if ((retval = mysql_stmt_bind_param(stmt, params))) { fprintf(stderr, "mysql_stmt_bind_param(), failed\\n"); fprintf(stderr, "%s\\n", mysql_error(conn)); return retval; }""") func.add_block("""if ((retval = mysql_stmt_execute(stmt))) { fprintf(stderr, "mysql_stmt_execute(), failed\\n"); fprintf(stderr, "%s\\n", mysql_error(conn)); return retval; }""") func.add_block("""if ((retval = mysql_stmt_close(stmt))) { fprintf(stderr, " failed while closing the statement\\n"); fprintf(stderr, " %s\\n", mysql_error(conn)); return retval; }""") return func
def body_delete(struct: Struct, func: FunctionTemplate): func.add_macro_def( MacroDefinition("QUERY", '"{}"'.format(delete_sql_string(struct)))) func.add_macro_def(MacroDefinition("PARAM_COUNT", str(1))) if struct.get_pk() is not None: func.add_block("assert({name}T->{pk_name} != 0);".format( name=struct.name, pk_name=struct.get_pk().name)) func.add_block('\tif (conn == NULL) {\n\t\tconn = db_init();\n\t}\n') func.add_block("""int retval;""") func.add_block(struct.get_col_param_buffer(["id_{}".format(struct.name)])) func.add_block( "retval = {}_execute(conn, QUERY, param, PARAM_COUNT);".format( struct.name)) func.add_block(struct.col_param_buffer_free(1)) func.add_block("return retval;") return func
def body_insert(struct: Struct, func: FunctionTemplate): func.add_macro_def(MacroDefinition("QUERY_LENGTH", "512")) func.add_macro_def(MacroDefinition("STRING_SIZE", "255")) func.add_macro_def( MacroDefinition("QUERY", '"{}"'.format(insert_sql_string(struct)))) func.add_macro_def( MacroDefinition("PARAM_COUNT", "{}".format(struct.param_count()))) func.add_block(struct.get_insert_assertions()) func.add_block(""" MYSQL_STMT* __attribute__((cleanup(mysql_stmt_cleanup))) stmt; uint retval; """) func.add_block('\tif (conn == NULL) {\n\t\tconn = db_init();\n\t}\n') func.add_block('\tstmt = mysql_stmt_init(conn);\n') func.add_block(struct.get_update_fk()) func.add_block(struct.col_param_lengths(func)) func.add_block(struct.get_col_param_buffers()) func.add_block("""if (mysql_stmt_prepare(stmt, QUERY, QUERY_LENGTH)) { fprintf(stderr, " mysql_stmt_prepare(), failed\\n"); fprintf(stderr, " %s\\n", mysql_stmt_error(stmt)); return 0U; }""") func.add_block("""if (mysql_stmt_bind_param(stmt, param)) { fprintf(stderr, " mysql_stmt_bind_param(), failed\\n"); fprintf(stderr, " %s\\n", mysql_stmt_error(stmt)); return 0U; }""") func.add_block("""if (mysql_stmt_execute(stmt)) { fprintf(stderr, " mysql_stmt_execute(), failed\\n"); fprintf(stderr, " %s\\n", mysql_stmt_error(stmt)); return 0U; }""") func.add_block("retval = (uint) mysql_stmt_insert_id(stmt);") if struct.get_pk() is not None: func.add_block( ("// update id after insertion;\n" "{name}T->{pk} = retval;\n").format(name=struct.name, pk=struct.get_pk().name)) func.add_block(struct.col_param_buffer_free()) func.add_block("return retval;") return func
def col_param_length(self, prop, func_ref: FunctionTemplate): """ Defines '#define' preprocessor directive and stack variable specifying size of the column field. """ func_ref.add_macro_def( MacroDefinition( "{name_upper}_SIZE".format(name_upper=prop.name.upper()), str(prop.size))) return """ unsigned long {name}_len; {name}_len = strnlen({struct}T->{name}, {name_upper}_SIZE); """.format(name=prop.name, name_upper=prop.name.upper(), struct=self.name)
def body_execute_find(struct: Struct, func: FunctionTemplate): func.add_macro_def(MacroDefinition("QUERY_SIZE", "512")) func.add_macro_def( MacroDefinition("RES_COL_COUNT", str(struct.col_count()))) func.add_macro_def(MacroDefinition("BUFFER_SIZE", "255")) func.add_block(""" SQL_RESULT* res; MYSQL_RES* prepare_meta_result; MYSQL_STMT* stmt;""") func.add_block('\tif (conn == NULL) {\n\t\tconn = db_init();\n\t}\n') func.add_block(struct.get_col_buffer_definitions()) func.add_block("stmt = mysql_stmt_init(conn);") func.add_block( """if (mysql_stmt_prepare(stmt, query, strnlen(query, QUERY_SIZE))) { fprintf(stderr, " mysql_stmt_prepare(), SELECT failed\\n"); fprintf(stderr, " %s\\n", mysql_stmt_error(stmt)); return NULL; } mysql_stmt_bind_param(stmt, params); assert(param_count == mysql_stmt_param_count(stmt));""") func.add_block("""/* Fetch result set meta information */ prepare_meta_result = mysql_stmt_result_metadata(stmt); if (!prepare_meta_result) { fprintf(stderr, " mysql_stmt_result_metadata(), returned no meta information\\n"); fprintf(stderr, " %s\\n", mysql_stmt_error(stmt)); return NULL; } assert(RES_COL_COUNT == mysql_num_fields(prepare_meta_result));""") func.add_block("""/* Execute the SELECT query */ if (mysql_stmt_execute(stmt)) { fprintf(stderr, " mysql_stmt_execute(), failed\\n"); fprintf(stderr, " %s\\n", mysql_stmt_error(stmt)); return NULL; }""") func.add_block(struct.get_buffer_bindings()) func.add_block("""/* Bind the result buffers */ if (mysql_stmt_bind_result(stmt, param)) { fprintf(stderr, " mysql_stmt_bind_result() failed\\n"); fprintf(stderr, " %s\\n", mysql_stmt_error(stmt)); return NULL; }""") func.add_block("""/* Now buffer all results to client (optional step) */ if (mysql_stmt_store_result(stmt)) { fprintf(stderr, " mysql_stmt_store_result() failed\\n"); fprintf(stderr, " %s\\n", mysql_stmt_error(stmt)); return NULL; }""") func.add_block("""/* Fetch all rows */ struct sql_result_row* row = NULL; struct sql_result_row* curr = NULL; res = calloc(1, sizeof(SQL_RESULT)); res->results = NULL; res->type = {enum_name}; res->count = 0;""".format(enum_name=struct.enum_name)) func.add_block(struct.col_fetch()) # TODO probably should remove error checking here v func.add_block("""/* Free the prepared result metadata */ mysql_free_result(prepare_meta_result); if (mysql_stmt_close(stmt)) { fprintf(stderr, " failed while closing the statement\\n"); fprintf(stderr, " %s\\n", mysql_error(conn)); mysql_res_free(&res); return NULL; }""") func.add_block("return res;")