/* ** W3C CVS To SQL Log Converter ** ** (c) COPRIGHT MIT 1999. ** Please first read the full copyright statement in the file COPYRIGH. ** @(#) $Id: cvs2sql.c,v 1.8 1999/04/12 19:00:32 frystyk Exp $ ** ** This program takes cvs log info via stdin and writes it to an SQL DB ** ** Author: ** Henrik Frystyk Nielsen, http://www.w3.org/People/Frystyk ** */ #include "WWWLib.h" /* Global Library Include file */ #include "WWWSQL.h" #include "HTextImp.h" #define APP_NAME "cvs2sql" #define APP_VERSION "1.0" #define DEFAULT_SQL_SERVER "localhost" #define DEFAULT_SQL_DB "cvs" #define DEFAULT_SQL_USER "none" #define DEFAULT_SQL_PW "none" #define DEFAULT_SQL_LOCATION_TABLE "locations" #define DEFAULT_SQL_USER_TABLE "users" #define DEFAULT_SQL_COMMENTS_TABLE "comments" #define DEFAULT_SQL_LOG_TABLE "logs" #define DEFAULT_SQL_KEY_TYPE "int unsigned not null" #define MAX_KEY_LENGTH 255 #define DEFAULT_CVS_USER "unknown" #define DELIMITERS " \n" #define BUFSIZE 8196 typedef enum _SQLFlags { SQL_CLEAR_LOCATION_TABLE = 0x1, SQL_DROP_LOCATION_TABLE = 0x2, SQL_CLEAR_USER_TABLE = 0x4, SQL_DROP_USER_TABLE = 0x8, SQL_CLEAR_COMMENTS_TABLE = 0x10, SQL_DROP_COMMENTS_TABLE = 0x20, SQL_CLEAR_LOG_TABLE = 0x40, SQL_DROP_LOG_TABLE = 0x80 } SQLFlags; /* ------------------------------------------------------------------------- */ PRIVATE void VersionInfo (void) { fprintf(stdout, "W3C Sample Software\n\n"); fprintf(stdout, "\t%s, W3C CVS Log to SQL converter version %s\n", APP_NAME, APP_VERSION); fprintf(stdout, "\tlibwww, W3C Sample Library version %s\n\n", HTLib_version()); fprintf(stdout, "Please send feedback to \n"); } PRIVATE void Cleanup (int status, HTSQL * sql, HTChunk * chunk) { HTChunk_delete(chunk); HTSQL_delete(sql); HTLibTerminate(); #ifdef VMS exit(status ? status : 1); #else exit(status ? status : 0); #endif } PRIVATE BOOL clear_table (HTSQL * me, const char * table) { if (me && table) { char buf[1024]; char * query = HTSQL_printf(buf, 1024, "delete from %s", table); return HTSQL_query(me, query); } return NO; } PRIVATE BOOL drop_table (HTSQL * me, const char * table) { if (me && table) { char buf[1024]; char * query = HTSQL_printf(buf, 1024, "drop table %s", table); return HTSQL_query(me, query); } return NO; } /* ** Create the three CVS tables if not already there ** location: filename, id ** user: username, id ** log: user_id, location_id, date, operation, message */ PRIVATE BOOL createTables (HTSQL * sql, SQLFlags flags) { if (sql) { char buf[1024]; char * query = NULL; /* Create location table */ /* If we have to delete it first */ if (flags & SQL_DROP_LOCATION_TABLE) drop_table(sql, DEFAULT_SQL_LOCATION_TABLE); query = HTSQL_printf(buf, 1024, "create table %s (id %s auto_increment, location varchar(%u) binary not null, primary key(id), unique(location), index loc_idx(location(32)))", DEFAULT_SQL_LOCATION_TABLE, DEFAULT_SQL_KEY_TYPE, MAX_KEY_LENGTH); HTSQL_query(sql, query); /* If we have to clear it out */ if (flags & SQL_CLEAR_LOCATION_TABLE) clear_table(sql, DEFAULT_SQL_LOCATION_TABLE); /* Create user table */ /* If we have to delete it first */ if (flags & SQL_DROP_USER_TABLE) drop_table(sql, DEFAULT_SQL_USER_TABLE); query = HTSQL_printf(buf, 1024, "create table %s (id %s auto_increment, username varchar(%u) binary not null, primary key(id), unique(username), index username_idx(username(32)))", DEFAULT_SQL_USER_TABLE, DEFAULT_SQL_KEY_TYPE, MAX_KEY_LENGTH); HTSQL_query(sql, query); /* If we have to clear it out */ if (flags & SQL_CLEAR_USER_TABLE) clear_table(sql, DEFAULT_SQL_USER_TABLE); /* Create comments table */ /* If we have to delete it first */ if (flags & SQL_DROP_COMMENTS_TABLE) drop_table(sql, DEFAULT_SQL_COMMENTS_TABLE); query = HTSQL_printf(buf, 1024, "create table %s (id %s auto_increment, comment text, primary key(id))", DEFAULT_SQL_COMMENTS_TABLE, DEFAULT_SQL_KEY_TYPE); HTSQL_query(sql, query); /* If we have to clear it out */ if (flags & SQL_CLEAR_COMMENTS_TABLE) clear_table(sql, DEFAULT_SQL_COMMENTS_TABLE); /* Create logs table */ /* If we have to delete it first */ if (flags & SQL_DROP_LOG_TABLE) drop_table(sql, DEFAULT_SQL_LOG_TABLE); query = HTSQL_printf(buf, 1024, "create table %s (location %s, username %s, date datetime, operation char(32), comment %s)", DEFAULT_SQL_LOG_TABLE, DEFAULT_SQL_KEY_TYPE, DEFAULT_SQL_KEY_TYPE, DEFAULT_SQL_KEY_TYPE); HTSQL_query(sql, query); /* If we have to clear it out */ if (flags & SQL_CLEAR_LOG_TABLE) clear_table(sql, DEFAULT_SQL_LOG_TABLE); /* All done */ return YES; } return NO; } PRIVATE int find_location(HTSQL * sql, const char * location) { int index = -1; if (sql && location) { char buf[4096]; char * query = NULL; MYSQL_RES * result = NULL; query = HTSQL_printf(buf, 4096, "select * from %s where location=%S", DEFAULT_SQL_LOCATION_TABLE, location); if (HTSQL_query(sql, query) && (result = HTSQL_storeResult(sql)) != NULL) { MYSQL_ROW row; if ((row = mysql_fetch_row(result)) && row[0]) index = atoi(row[0]); HTSQL_freeResult(result); } } return index; } PRIVATE int add_location (HTSQL * sql, const char * location) { if (sql && location) { int index = -1; /* If we can't find the LOCATION then add it */ if ((index = find_location(sql, location)) < 0) { char buf[4096]; char * query = HTSQL_printf(buf, 4096, "insert into %s (location) values (%S)", DEFAULT_SQL_LOCATION_TABLE, location); if (HTSQL_query(sql, query) != YES) { return -1; } index = HTSQL_getLastInsertId(sql); } return index; } return -1; } PRIVATE int find_user(HTSQL * sql, const char * user) { int index = -1; if (sql && user) { char buf[1024]; char * query = NULL; MYSQL_RES * result = NULL; query = HTSQL_printf(buf, 1024, "select * from %s where username=%S", DEFAULT_SQL_USER_TABLE, user); if (HTSQL_query(sql, query) && (result = HTSQL_storeResult(sql)) != NULL) { MYSQL_ROW row; if ((row = mysql_fetch_row(result)) && row[0]) index = atoi(row[0]); HTSQL_freeResult(result); } } return index; } PRIVATE int add_user (HTSQL * sql, const char * user) { if (sql && user) { int index = -1; /* If we can't find the USER then add it */ if ((index = find_user(sql, user)) < 0) { char buf[1024]; char * query = HTSQL_printf(buf, 1024, "insert into %s (username) values (%S)", DEFAULT_SQL_USER_TABLE, user); if (HTSQL_query(sql, query) != YES) { return -1; } index = HTSQL_getLastInsertId(sql); } return index; } return -1; } PRIVATE int add_comment (HTSQL * sql, const char * comment) { if (sql && comment) { char buf[8196]; char * query = HTSQL_printf(buf, 8196, "insert into %s (comment) values (%S)", DEFAULT_SQL_COMMENTS_TABLE, comment); if (HTSQL_query(sql, query) != YES) return -1; return HTSQL_getLastInsertId(sql); } return -1; } int main (int argc, char ** argv) { HTSQL * sql = NULL; char * sqlserver = DEFAULT_SQL_SERVER; char * sqldb = DEFAULT_SQL_DB; char * sqluser = DEFAULT_SQL_USER; char * sqlpw = DEFAULT_SQL_PW; char * cvsuser = DEFAULT_CVS_USER; time_t cvsdate = -1; FILE * fin = stdin; char * input_buffer[BUFSIZE]; HTChunk * loginfo = HTChunk_new(BUFSIZE); int arg = 0; BOOL create_db = YES; /* Initiate libwww */ HTLibInit(APP_NAME, APP_VERSION); /* Scan command line for parameters */ for (arg=1; argHTChunk_data(loginfo) && *p && *p!='\n'; p--); p++; operation = HTNextField(&p); /* Find the next line */ if ((q = strchr(files, '\n')) != NULL) { *q++ = '\0'; ptr = q; } /* Create the query */ if (operation && files && comment) { char * file; int location_id = -1; #ifdef HT_REENTRANT if ((file = strtok_r(files, DELIMITERS, &lasts)) != NULL) { #else if ((file = strtok(files, DELIMITERS)) != NULL) { #endif /* HT_REENTRANT */ do { char * path = NULL; StrAllocMCopy(&path, root, "/", file, NULL); /* Add/find location and get id */ if ((location_id = add_location(sql, path)) < 0) { Cleanup(-1, sql, loginfo); break; } #if 0 fprintf(stderr, "location: `%s\', user: `%s\', operation: `%s\', comment: `%s\'\n", path, cvsuser, operation, comment); #endif /* Add log entry */ { char buf[16384]; char * query = HTSQL_printf(buf, 16384, "insert into %s values (%u,%u,%T,%S,%u)", DEFAULT_SQL_LOG_TABLE, location_id, user_id, cvsdate, operation, comment_id); if (HTSQL_query(sql, query) != YES) { Cleanup(-1, sql, loginfo); break; } } HT_FREE(path); #ifdef HT_REENTRANT } while ((file = (char *) strtok_r(NULL, DELIMITERS, &lasts)) != NULL); #else } while ((file = strtok(NULL, DELIMITERS)) != NULL); #endif /* HT_REENTRANT */ } } } } return 0; }