mirror of
https://github.com/owntone/owntone-server.git
synced 2024-12-24 22:25:56 -05:00
first pass of sql generation. Some problems in the production rules, I think, but coming along
This commit is contained in:
parent
b32984abeb
commit
dda666ea8e
@ -35,6 +35,9 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
pt=sp_init();
|
||||
sp_parse(pt,argv[optind]);
|
||||
|
||||
printf("SQL: %s\n",sp_sql_clause(pt));
|
||||
|
||||
sp_dispose(pt);
|
||||
|
||||
printf("Done!\n");
|
||||
|
@ -202,6 +202,7 @@ SP_NODE *sp_parse_string_criterion(PARSETREE tree);
|
||||
SP_NODE *sp_parse_int_criterion(PARSETREE tree);
|
||||
SP_NODE *sp_parse_date_criterion(PARSETREE tree);
|
||||
void sp_free_node(SP_NODE *);
|
||||
int sp_node_size(SP_NODE *);
|
||||
|
||||
/**
|
||||
* see if a string is actually a number
|
||||
@ -843,6 +844,97 @@ int sp_dispose(PARSETREE tree) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* calculate the size required to render the tree as a
|
||||
* sql query.
|
||||
*
|
||||
* @parameter node node/tree to calculate
|
||||
* @returns size in bytes of sql "where" clause
|
||||
*/
|
||||
int sp_node_size(SP_NODE *node) {
|
||||
int size;
|
||||
|
||||
if(node->op_type == SP_OPTYPE_ANDOR) {
|
||||
size = sp_node_size(node->left.node);
|
||||
size += sp_node_size(node->right.node);
|
||||
size += 7; /* (xxx AND xxx) */
|
||||
} else {
|
||||
size = 4; /* parens, plus spaces around op */
|
||||
size += strlen(node->left.field);
|
||||
if((node->op & 0x0FFF) > T_LAST) {
|
||||
DPRINTF(E_FATAL,L_PARSE,"Can't determine node size: op %04x\n",
|
||||
node->op);
|
||||
} else {
|
||||
size += strlen(sp_token_descr[node->op & 0x0FFF]);
|
||||
}
|
||||
if(node->op_type == SP_OPTYPE_STRING)
|
||||
size += (2 + strlen(node->right.cvalue));
|
||||
if(node->op_type == SP_OPTYPE_INT)
|
||||
size += ((node->right.ivalue/10) + 1);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* serialize node into pre-allocated string
|
||||
*
|
||||
* @param node node to serialize
|
||||
* @param string string to generate
|
||||
*/
|
||||
void sp_serialize_sql(SP_NODE *node, char *string) {
|
||||
char buffer[40];
|
||||
|
||||
if(node->op_type == SP_OPTYPE_ANDOR) {
|
||||
strcat(string,"(");
|
||||
sp_serialize_sql(node->left.node,string);
|
||||
if(node->op == T_AND) strcat(string," and ");
|
||||
if(node->op == T_OR) strcat(string," or ");
|
||||
sp_serialize_sql(node->right.node,string);
|
||||
strcat(string,")");
|
||||
} else {
|
||||
strcat(string,"(");
|
||||
strcat(string,node->left.field);
|
||||
strcat(string," ");
|
||||
strcat(string,sp_token_descr[node->op & 0x0FFF]);
|
||||
strcat(string," ");
|
||||
if(node->op_type == SP_OPTYPE_STRING) {
|
||||
strcat(string,"'");
|
||||
strcat(string,node->right.cvalue);
|
||||
strcat(string,"'");
|
||||
}
|
||||
|
||||
if(node->op_type == SP_OPTYPE_INT) {
|
||||
sprintf(buffer,"%d",node->right.ivalue);
|
||||
strcat(string,buffer);
|
||||
}
|
||||
strcat(string,")");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* generate sql "where" clause
|
||||
*
|
||||
* @param node node/tree to calculate
|
||||
* @returns sql string. Must be freed by caller
|
||||
*/
|
||||
char *sp_sql_clause(PARSETREE tree) {
|
||||
int size;
|
||||
char *sql;
|
||||
|
||||
size = sp_node_size(tree->tree);
|
||||
sql = (char*)malloc(size+1);
|
||||
|
||||
memset(sql,0x00,size+1);
|
||||
sp_serialize_sql(tree->tree,sql);
|
||||
|
||||
return sql;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* if there was an error in a previous action (parsing?)
|
||||
|
@ -11,6 +11,7 @@ extern PARSETREE sp_init(void);
|
||||
extern int sp_parse(PARSETREE *tree, char *term);
|
||||
extern int sp_dispose(PARSETREE tree);
|
||||
extern char *sp_geterror(PARSETREE tree);
|
||||
char *sp_sql_clause(PARSETREE tree);
|
||||
|
||||
#endif /* _SMART_PARSER_H_ */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user