📄 sql_parser.c
字号:
#include <stdio.h>#include <glib.h>#include <string.h>#include "sql_parser.h"#include "sql_tree.h"#include "mem.h"extern char *sqltext;extern void sql_switch_to_buffer(void *buffer);extern void *sql_scan_string(const char *string);int sqlerror(char *error);sql_statement *sql_result;int sqlparse(void);static int sql_destroy_select(sql_select_statement * select);static int sql_destroy_insert(sql_insert_statement * insert);static char *sql_select_stringify(sql_select_statement * select);static int sql_destroy_field(sql_field * field);static char *sql_field_stringify(sql_field * field);/** * sqlerror: * * Internal function for displaying error messages used by the lexer parser. */intsqlerror(char *string) { fprintf(stderr, "SQL Parser error: %s near `%s'\n", string, sqltext); return 0; }static intsql_destroy_field_item(sql_field_item * item) { GList *walk; if (!item) return 0; switch (item->type) { case SQL_name: for (walk = item->d.name; walk != NULL; walk = walk->next) memsql_free(walk->data); g_list_free(item->d.name); break; case SQL_equation: sql_destroy_field_item(item->d.equation.left); sql_destroy_field_item(item->d.equation.right); break; case SQL_inlineselect: sql_destroy_select(item->d.select); break; case SQL_function: memsql_free (item->d.function.funcname); for (walk = item->d.function.funcarglist; walk != NULL; walk = walk->next) sql_destroy_field (walk->data); g_list_free (item->d.function.funcarglist); } memsql_free(item); return 0; }static intsql_destroy_field(sql_field * field) { if (!field) return 0; sql_destroy_field_item(field->item); memsql_free(field->as); memsql_free(field); return 0; }static intsql_destroy_condition(sql_condition * cond) { if (!cond) return 0; switch (cond->op) { case SQL_eq: case SQL_is: case SQL_not: case SQL_in: case SQL_notin: case SQL_like: sql_destroy_field(cond->d.pair.left); sql_destroy_field(cond->d.pair.right); break; case SQL_between: sql_destroy_field(cond->d.between.field); sql_destroy_field(cond->d.between.lower); sql_destroy_field(cond->d.between.upper); break; } memsql_free(cond); return 0; }static intsql_destroy_table(sql_table * table) { if (!table) return 0; switch (table->type) { case SQL_simple: memsql_free(table->d.simple); break; case SQL_join: sql_destroy_table(table->d.join.left); sql_destroy_table(table->d.join.right); sql_destroy_condition(table->d.join.cond); break; case SQL_nestedselect: sql_destroy_select(table->d.select); break; } memsql_free(table); return 0; }static intsql_destroy_where(sql_where * where) { if (!where) return 0; switch (where->type) { case SQL_single: sql_destroy_condition(where->d.single); break; case SQL_negated: sql_destroy_where(where->d.negated); break; case SQL_pair: sql_destroy_where(where->d.pair.left); sql_destroy_where(where->d.pair.right); break; } memsql_free(where); return 0; }static intsql_destroy_insert(sql_insert_statement * insert) { GList *walk; sql_destroy_table(insert->table); for (walk = insert->fields; walk != NULL; walk = walk->next) sql_destroy_field(walk->data); g_list_free(insert->fields); for (walk = insert->values; walk != NULL; walk = walk->next) sql_destroy_field(walk->data); g_list_free(insert->values); memsql_free(insert); return 0; }static intsql_destroy_select(sql_select_statement * select) { GList *walk; for (walk = select->fields; walk != NULL; walk = walk->next) sql_destroy_field(walk->data); for (walk = select->from; walk != NULL; walk = walk->next) sql_destroy_table(walk->data); for (walk = select->order; walk != NULL; walk = walk->next) sql_destroy_field(walk->data); for (walk = select->group; walk != NULL; walk = walk->next) sql_destroy_field(walk->data); g_list_free(select->fields); g_list_free(select->from); g_list_free(select->order); g_list_free(select->group); sql_destroy_where(select->where); memsql_free(select); return 0; }static intsql_destroy_update (sql_update_statement *update){ GList *walk; sql_destroy_table (update->table); for (walk = update->set; walk != NULL; walk = walk->next) sql_destroy_condition (walk->data); g_list_free (update->set); sql_destroy_where (update->where); memsql_free (update); return 0;}/** * sql_destroy: * @statement: Sql statement generated by sql_parse() * * Free up a sql_statement generated by sql_parse(). */intsql_destroy(sql_statement * statement) { if (!statement) return 0; switch (statement->type) { case SQL_select: sql_destroy_select(statement->statement); break; case SQL_insert: sql_destroy_insert(statement->statement); break; case SQL_update: sql_destroy_update (statement->statement); break; default: fprintf(stderr, "Unknown statement type: %d\n", statement->type); } memsql_free(statement->full_query); memsql_free(statement); return 0; }/** * sql_parse: * @sqlquery: A SQL query string. ie SELECT * FROM FOO * * Generate in memory a structure of the @sqlquery in an easy * to view way. You can also modify the returned structure and * regenerate the sql query using sql_stringify(). The structure * contains information on what type of sql statement it is, what * tables its getting from, what fields are selected, the where clause, * joins etc. * * Returns: A generated sql_statement or %NULL on error. */sql_statement *sql_parse(char *sqlquery) { if (sqlquery == NULL) { fprintf(stderr, "SQL parse error, you can not specify NULL"); return NULL; } sql_switch_to_buffer(sql_scan_string(sqlquery)); if (sqlparse() == 0) { sql_result->full_query = memsql_strdup(sqlquery); return sql_result; } else { fprintf(stderr, "Error on SQL statement: %s\n", sqlquery); return NULL; } }static char *sql_field_op_stringify(sql_field_operator op) { switch (op) { case SQL_plus: return memsql_strdup("+"); case SQL_minus: return memsql_strdup("-"); case SQL_times: return memsql_strdup("*"); case SQL_div: return memsql_strdup("/"); } fprintf(stderr, "Invalid op: %d\n", op); return NULL; }static char *sql_field_name_stringify(GList * name) { GList *walk; char *result = NULL; for (walk = name; walk != NULL; walk = walk->next) { result = memsql_strappend_free(result, memsql_strdup(walk->data)); if (walk->next) result = memsql_strappend_free(result, memsql_strdup(".")); } return result; }static char *sql_field_item_stringify(sql_field_item * item) { char *retval = NULL; GList *walk; if (!item) return NULL; switch (item->type) { case SQL_name: retval = sql_field_name_stringify(item->d.name); break; case SQL_equation: retval = memsql_strappend_free(sql_field_item_stringify(item->d.equation.left), sql_field_op_stringify(item->d.equation.op)); retval = memsql_strappend_free(retval, sql_field_item_stringify(item->d.equation.right)); break; case SQL_inlineselect: retval = memsql_strappend_free(memsql_strdup("("), sql_select_stringify(item->d.select)); retval = memsql_strappend_free(retval, memsql_strdup(")")); break; case SQL_function: retval = memsql_strappend_free (memsql_strdup (item->d.function.funcname), memsql_strdup ("(")); for (walk = item->d.function.funcarglist; walk != NULL; walk = walk->next) { retval = memsql_strappend_free (retval, sql_field_stringify (walk->data)); if (walk->next) retval = memsql_strappend_free (retval, memsql_strdup (", ")); } retval = memsql_strappend_free (retval, memsql_strdup (")")); break; } return retval; }static char *sql_field_stringify(sql_field * field) { char *retval; if (!field) return NULL; retval = sql_field_item_stringify(field->item); if (field->as) { retval = memsql_strappend_free(retval, memsql_strdup(" as ")); retval = memsql_strappend_free(retval, memsql_strdup(field->as)); } return retval; }static char *sql_condition_op_stringify(sql_condition_operator op) { switch (op) { case SQL_eq: return memsql_strdup("="); case SQL_is: return memsql_strdup("is"); case SQL_not: return memsql_strdup("not"); case SQL_like: return memsql_strdup("like"); case SQL_in: return memsql_strdup("in"); case SQL_notin: return memsql_strdup("not in"); default: fprintf(stderr, "Invalid condition op: %d\n", op); } return NULL; }static char *sql_condition_stringify(sql_condition * cond) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -