bin/create/create.c
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- escape_apostrophes
- each_attribute_to_string
- object_to_string
- attribute_new
- object_free
- object_new
- line_type
- rollback
- commit
- each_attribute_update
- transaction_free
- transaction_new
- perform_updates
- object_process
- object_discard
- main
/***************************************
$Revision: 1.2 $
Example code: Create
Status: NOT REVUED, NOT TESTED
Author: Chris Ottrey
+html+ <DL COMPACT>
+html+ <DT>Online References:
+html+ <DD><UL>
+html+ </UL>
+html+ </DL>
******************/ /******************
Modification History:
ottrey (01/11/1999) Created.
******************/ /******************
Copyright (c) 1999 RIPE NCC
All Rights Reserved
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the name of the author not be
used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
***************************************/
#include <stdio.h>
#include <strings.h>
#include <glib.h>
#include "defs.h"
#include "mysql_driver.h"
#define DEFAULT_PROP_FILE_NAME ".properties"
/*+ String sizes +*/
#define STR_S 63
#define STR_M 255
#define STR_L 1023
#define STR_XL 4095
#define STR_XXL 16383
typedef enum _Line_Type_t {
LINE_ATTRIBUTE,
LINE_COMMENT,
LINE_EMPTY,
LINE_EOF
} Line_Type_t;
typedef struct _Attribute_t {
A_Type_t type;
char *value;
} Attribute_t;
typedef struct _Object_t {
C_Type_t type;
GSList *attributes;
} Object_t;
typedef struct _Transaction {
SQ_connection_t *sql_connection;
int thread_id;
C_Type_t class_type;
int succeeded;
} Transaction_t;
char * const Tables[] = {
"ac",
"an",
"dn",
"tc",
"zc",
"nh",
"object",
NULL
}; /* Tables */
#include "UD_updates.def"
static void escape_apostrophes(GString *text) {
/* [<][>][^][v][top][bottom][index][help] */
int i;
for (i=0; i < text->len; i++) {
if (text->str[i] == '\'') {
g_string_insert_c(text, i, '\\');
i++;
}
}
} /* escape_apostrophes() */
static void each_attribute_to_string(void *element_data, void *result_ptr) {
/* [<][>][^][v][top][bottom][index][help] */
Attribute_t *attr = element_data;
GString *result = (GString *)result_ptr;
GString *value = g_string_new(attr->value);
escape_apostrophes(value);
g_string_sprintfa(result, "%s: \t%s\n", DF_get_attribute_name(attr->type), value->str);
} /* each_attribute_to_string() */
static char *object_to_string(const Object_t *obj) {
/* [<][>][^][v][top][bottom][index][help] */
GString *result = g_string_sized_new(STR_XL);
g_slist_foreach(obj->attributes, each_attribute_to_string, result);
return result->str;
} /* object_to_string() */
static Attribute_t *attribute_new(const char *line) {
/* [<][>][^][v][top][bottom][index][help] */
Attribute_t *attr = NULL;
int type;
char *colon;
gchar *token;
colon = index(line, ':');
if (colon != NULL) {
if (line[0] =='*') {
token = g_strndup(line+1, 2);
type = DF_attribute_code2type(token);
}
else {
token = g_strndup(line, (colon - line));
type = DF_attribute_name2type(token);
}
if (type >= 0) {
char *n;
attr = (Attribute_t *)calloc(1, sizeof(Attribute_t)+1);
attr->type = type;
attr->value = g_strdup((colon+2));
/* Remove the tailing \n */
n = index(attr->value, '\n');
if (n != NULL) {
*n = '\0';
}
/* Strip the whitespace */
g_strstrip(attr->value);
}
else {
fprintf(stderr, "ERROR: Bad attribute: %s\n", token);
}
}
else {
fprintf(stderr, "ERROR: Not an attribute: %s\n", line);
}
return attr;
} /* attribute_new() */
static object_free(Object_t *obj) {
/* [<][>][^][v][top][bottom][index][help] */
g_slist_free(obj->attributes);
free(obj);
} /* object_free() */
static Object_t *object_new(const char *line) {
/* [<][>][^][v][top][bottom][index][help] */
Object_t *obj = NULL;
int type;
char *colon;
gchar *token;
colon = index(line, ':');
if (colon != NULL) {
if (line[0] =='*') {
token = g_strndup(line+1, 2);
type = DF_class_code2type(token);
}
else {
token = g_strndup(line, (colon - line));
type = DF_class_name2type(token);
}
if (type >= 0) {
obj = (Object_t *)calloc(1, sizeof(Object_t)+1);
obj->attributes = NULL;
obj->type = type;
}
else {
fprintf(stderr, "ERROR: Object has an invalid class: %s\n", token);
}
}
else {
fprintf(stderr, "ERROR: No colon found in line: %s\n", line);
}
return obj;
} /* object_new() */
static Line_Type_t line_type(const char *line) {
/* [<][>][^][v][top][bottom][index][help] */
Line_Type_t result = -1;
int i;
char * const *attr_aliases = DF_get_attribute_aliases();
char attr_code[2];
if (strncmp(line, "# EOF", 4) == 0) {
result = LINE_EOF;
}
else if (strncmp(line, "#", 1) == 0) {
result = LINE_COMMENT;
}
else if (strcmp(line, "\n") == 0) {
result = LINE_EMPTY;
}
else {
result = LINE_ATTRIBUTE;
}
return result;
} /* line_type() */
static rollback(Transaction_t *tr) {
/* [<][>][^][v][top][bottom][index][help] */
GString *query = g_string_sized_new(STR_XL);
int i;
for (i=0; Tables[i] != NULL; i++) {
g_string_sprintf(query, "DELETE FROM %s WHERE thread_id=%d", Tables[i], tr->thread_id);
SQ_execute_query(tr->sql_connection, query->str);
printf("%s\n", query->str);
}
g_string_free(query, TRUE);
} /* rollback() */
static commit(Transaction_t *tr) {
/* [<][>][^][v][top][bottom][index][help] */
GString *query = g_string_sized_new(STR_XL);
int i;
for (i=0; Tables[i] != NULL; i++) {
g_string_sprintf(query, "UPDATE %s SET thread_id=0 WHERE thread_id=%d", Tables[i], tr->thread_id);
SQ_execute_query(tr->sql_connection, query->str);
printf("%s\n", query->str);
}
g_string_free(query, TRUE);
} /* commit() */
static void each_attribute_update(void *element_data, void *tr_ptr) {
/* [<][>][^][v][top][bottom][index][help] */
my_ulonglong num;
char *query_fmt;
Attribute_t *attr = element_data;
Transaction_t *tr = (Transaction_t *)tr_ptr;
query_fmt = Update[attr->type];
if (strcmp(query_fmt, "") != 0) {
GString *query = g_string_sized_new(STR_XL);
// g_string_sprintf(query, "INSERT %s SELECT nh.id, max(object.id), object_type.id, %d FROM nh, object, object_type WHERE nh.value='%s' AND object_type.code='%s' GROUP BY object_type.code", DF_get_attribute_code(attr->type), tr->thread_id, attr->value, DF_get_class_code(tr->class_type));
g_string_sprintf(query, query_fmt, tr->thread_id, attr->value, DF_get_class_code(tr->class_type));
printf("%s\n", query->str);
SQ_execute_query(tr->sql_connection, query->str);
num = mysql_affected_rows(tr->sql_connection);
if ((num == -1) || (num == 0)) {
printf("A ERROR!: %lld\n", num);
tr->succeeded=0;
}
g_string_free(query, TRUE);
}
} /* each_attribute_update() */
static void transaction_free(Transaction_t *tr) {
/* [<][>][^][v][top][bottom][index][help] */
free(tr);
} /* transaction_free() */
static Transaction_t *transaction_new(SQ_connection_t *sql_connection, C_Type_t class_type) {
/* [<][>][^][v][top][bottom][index][help] */
Transaction_t *tr = (Transaction_t *)calloc(1, sizeof(Transaction_t));
if (tr != NULL) {
tr->sql_connection = sql_connection;
tr->class_type = class_type;
tr->thread_id = mysql_thread_id(sql_connection);
tr->succeeded = 1;
}
return tr;
} /* transaction_new() */
static void perform_updates(const Object_t *obj, Transaction_t *tr) {
/* [<][>][^][v][top][bottom][index][help] */
char *str;
GString *query = g_string_sized_new(STR_XL);
my_ulonglong num;
if (tr != NULL) {
if (tr->sql_connection != NULL) {
str = object_to_string(obj);
g_string_sprintf(query, "INSERT INTO object SET value='%s', thread_id=%d", str, tr->thread_id);
printf("%s\n", query->str);
SQ_execute_query(tr->sql_connection, query->str);
num = mysql_affected_rows(tr->sql_connection);
if ((num == -1) || (num == 0)) {
printf("B ERROR!: %lld\n", num);
tr->succeeded=0;
}
g_slist_foreach(obj->attributes, each_attribute_update, tr);
free(str);
}
}
g_string_free(query, TRUE);
} /* perform_updates() */
static object_process(const Object_t *obj) {
/* [<][>][^][v][top][bottom][index][help] */
SQ_connection_t *sql_connection;
int thread_id;
Transaction_t *tr = NULL;
//sql_connection = SQ_get_connection("rowan.ripe.net", 3306, "test", "dbint", "reimp");
sql_connection = SQ_get_connection2();
if (sql_connection) {
tr = transaction_new(sql_connection, obj->type);
if (tr != NULL) {
perform_updates(obj, tr);
if (tr->succeeded == 1) {
commit(tr);
}
else {
rollback(tr);
}
transaction_free(tr);
}
SQ_close_connection(sql_connection);
}
} /* object_process() */
static object_discard(Object_t *obj) {
/* [<][>][^][v][top][bottom][index][help] */
char *str;
fprintf(stderr, "ERROR: Bad attribute in object => discard\n");
str = object_to_string(obj);
fprintf(stderr, "%s", str);
free(str);
object_free(obj);
} /* object_discard() */
int main(int argc, char** argv) {
/* [<][>][^][v][top][bottom][index][help] */
char *prop_file_name;
FILE *file;
char *line = NULL;
char line_buff[STR_XXL];
Attribute_t *attr;
Object_t *obj;
int start_object = 1;
/* 1. Get the properties file name from argv[1] (Defaults to ".properties" if none specified) */
if (argc == 2) {
prop_file_name = (char *)calloc(1, strlen(argv[1])+1 );
strcpy(prop_file_name,argv[1]);
} else {
prop_file_name = (char *)calloc(1, strlen(DEFAULT_PROP_FILE_NAME)+1 );
strcpy(prop_file_name, DEFAULT_PROP_FILE_NAME);
}
printf("Loading properties from prop_file_name=%s\n", prop_file_name);
/* 2. Load properties object from prop_file. */
PR_load(prop_file_name); printf("%s\n", PR_to_string() );
/* 3. Set the constants. */
CO_set(); printf("%s\n", CO_to_string() );
file=fopen("ripe.pet10", "r");
while (fgets(line_buff, STR_XXL, file) != NULL) {
switch (line_type(line_buff)) {
case LINE_ATTRIBUTE:
if (start_object == 1) {
start_object = 0;
obj = object_new(line_buff);
}
if (obj != NULL) {
attr = attribute_new(line_buff);
if (attr != NULL) {
obj->attributes = g_slist_append(obj->attributes, attr);
}
else {
object_discard(obj);
obj = NULL;
}
}
break;
case LINE_COMMENT:
break;
case LINE_EOF:
break;
case LINE_EMPTY:
if (obj != NULL) {
object_process(obj);
object_free(obj);
obj = NULL;
}
start_object=1;
break;
default:
fprintf(stderr, "ERROR: Bad line type\n");
} /* switch */
} /* while */
return(0);
} /* main() */