Annotation of libwww/Library/src/HTSQLLog.c, revision 2.4

2.1       frystyk     1: /*                                                                HTSQL.c
                      2: **     SQL LOGGING MODULE
                      3: **
                      4: **     (c) COPYRIGHT MIT 1995.
                      5: **     Please first read the full copyright statement in the file COPYRIGH.
2.4     ! vbancrof    6: **     @(#) $Id: HTSQLLog.c,v 2.3 1999/02/22 22:10:12 frystyk Exp $
2.1       frystyk     7: **
                      8: **     This module contains a simple SQL based logging mechanism for requests
                      9: **     and anything else you want to log
                     10: **
                     11: ** History:
                     12: **     23 Apr 98       Henrik Frystyk, frystyk@w3.org
                     13: */
                     14: 
                     15: /* Library include files */
                     16: #include "WWWLib.h"
2.2       frystyk    17: #include "HTSQL.h"
2.1       frystyk    18: #include "HTSQLLog.h"                                   /* Implemented here */
                     19: 
2.4     ! vbancrof   20: #include <mysql.h>
2.1       frystyk    21: 
                     22: struct _HTSQLLog {
2.2       frystyk    23:     HTSQL *            sql;
2.1       frystyk    24:     char *             relative;               /* Make URIs relative to */
                     25:     int                        accesses;
2.2       frystyk    26:     HTSQLLogFlags      flags;
2.1       frystyk    27: };
                     28: 
                     29: #define DEFAULT_SQL_URIS_TABLE         "uris"
                     30: #define DEFAULT_SQL_REQUESTS_TABLE     "requests"
                     31: #define DEFAULT_SQL_RESOURCES_TABLE    "resources"
                     32: #define DEFAULT_SQL_LINKS_TABLE                "links"
                     33: 
2.2       frystyk    34: #define DEFAULT_SQL_KEY_TYPE           "int unsigned not null"
                     35: #define MAX_URI_LENGTH                 255
2.1       frystyk    36: 
                     37: /* ------------------------------------------------------------------------- */
                     38: 
                     39: PRIVATE int find_uri(HTSQLLog * me, const char * uri)
                     40: {
                     41:     int index = -1;
2.2       frystyk    42:     if (me && me->sql && uri) {
2.1       frystyk    43:        char buf[1024];
                     44:         char * query = NULL;
                     45:         MYSQL_RES * result = NULL;
2.2       frystyk    46:        query = HTSQL_printf(buf, 1024, "select * from %s where uri=%S",
                     47:                             DEFAULT_SQL_URIS_TABLE, uri);
                     48:        if (HTSQL_query(me->sql, query) &&
                     49:            (result = HTSQL_storeResult(me->sql)) != NULL) {
2.1       frystyk    50:            MYSQL_ROW row;
                     51:            if ((row = mysql_fetch_row(result)) && row[0])
                     52:                index = atoi(row[0]);
2.2       frystyk    53:            HTSQL_freeResult(result);
2.1       frystyk    54:        }
                     55:     }
                     56:     return index;
                     57: }
                     58: 
                     59: PRIVATE int add_uri (HTSQLLog * me, const char * uri)
                     60: {
2.2       frystyk    61:     if (me && me->sql && uri) {
2.1       frystyk    62:        int index = -1;
                     63:        char * rel = me->relative ? HTRelative(uri, me->relative) : NULL;
                     64: 
                     65:        /* If we can't find the URI then add it */
                     66:        if ((index = find_uri(me, rel ? rel : uri)) < 0) {
                     67:            char buf[1024];
2.2       frystyk    68:            char * query = HTSQL_printf(buf, 1024, "insert into %s (uri) values (%S)",
                     69:                                        DEFAULT_SQL_URIS_TABLE, rel ? rel : uri);
                     70:            if (HTSQL_query(me->sql, query) != YES) {
2.1       frystyk    71:                HT_FREE(rel);
                     72:                return -1;
                     73:            }
2.2       frystyk    74:            index = HTSQL_getLastInsertId(me->sql);
2.1       frystyk    75:        }
                     76:        HT_FREE(rel);
                     77:        return index;
                     78:     }
                     79:     return -1;
                     80: }
                     81: 
                     82: PRIVATE BOOL add_linktype (HTSQLLog * me, int srcidx, int dstidx,
                     83:                           const char * type, const char * comment)
                     84: {
2.2       frystyk    85:     if (me && me->sql && srcidx>=0 && dstidx>=0 && type) {
2.1       frystyk    86:        char buf[1024];
2.2       frystyk    87:        char * query = HTSQL_printf(buf, 1024, "insert into %s values (%u,%u,%S,%S)",
                     88:                                    DEFAULT_SQL_LINKS_TABLE,
                     89:                                    srcidx, dstidx, type, comment);
                     90:        return HTSQL_query(me->sql, query);
2.1       frystyk    91:     }
                     92:     return NO;
                     93: }
                     94: 
                     95: PRIVATE BOOL clear_table (HTSQLLog * me, const char * table)
                     96: {
2.2       frystyk    97:     if (me && me->sql && table) {
                     98:        char buf[1024];
                     99:        char * query = HTSQL_printf(buf, 1024, "delete from %s", table);
                    100:        return HTSQL_query(me->sql, query);
2.1       frystyk   101:     }
2.2       frystyk   102:     return NO;
2.1       frystyk   103: }
                    104: 
                    105: PRIVATE BOOL drop_table (HTSQLLog * me, const char * table)
                    106: {
2.2       frystyk   107:     if (me && me->sql && table) {
                    108:        char buf[1024];
                    109:        char * query = HTSQL_printf(buf, 1024, "drop table %s", table);
                    110:        return HTSQL_query(me->sql, query);
2.1       frystyk   111:     }
2.2       frystyk   112:     return NO;
2.1       frystyk   113: }
                    114: 
                    115: PRIVATE BOOL createTables (HTSQLLog * me, HTSQLLogFlags flags)
                    116: {
2.2       frystyk   117:     if (me && me->sql) {
                    118:        char buf[1024];
2.1       frystyk   119:        char * query = NULL;
                    120: 
                    121:        /* If we have to delete it first */
                    122:        if (flags & HTSQLLOG_DROP_URIS_TABLE) 
                    123:            drop_table(me, DEFAULT_SQL_URIS_TABLE);
                    124: 
                    125:        /* Create URI table (which is the index) */
2.2       frystyk   126:        query = HTSQL_printf(buf, 1024,
                    127:                             "create table %s (id %s auto_increment, uri varchar(%u) binary not null, primary key(id), unique (uri), index uri_idx (uri(32)))",
                    128:                             DEFAULT_SQL_URIS_TABLE,
                    129:                             DEFAULT_SQL_KEY_TYPE,
                    130:                             MAX_URI_LENGTH);
                    131:        HTSQL_query(me->sql, query);
2.1       frystyk   132: 
                    133:        /* If we have to clear it out */
                    134:        if (flags & HTSQLLOG_CLEAR_URIS_TABLE) 
                    135:            clear_table(me, DEFAULT_SQL_URIS_TABLE);
                    136: 
                    137:        /* If we have to delete it first */
                    138:        if (flags & HTSQLLOG_DROP_REQUESTS_TABLE) 
                    139:            drop_table(me, DEFAULT_SQL_REQUESTS_TABLE);
                    140: 
                    141:        /* Create Request table */
2.2       frystyk   142:        query = HTSQL_printf(buf, 1024,
                    143:                             "create table %s (uri %s primary key, method char(16) not null, status int unsigned not null, request_time datetime, response_time datetime)",
                    144:                             DEFAULT_SQL_REQUESTS_TABLE,
                    145:                             DEFAULT_SQL_KEY_TYPE);
                    146:        HTSQL_query(me->sql, query);
2.1       frystyk   147: 
                    148:        /* If we have to clear it out */
                    149:        if (flags & HTSQLLOG_CLEAR_REQUESTS_TABLE) 
                    150:            clear_table(me, DEFAULT_SQL_REQUESTS_TABLE);
                    151: 
                    152:        /* If we have to delete it first */
                    153:        if (flags & HTSQLLOG_DROP_RESOURCES_TABLE) 
                    154:            drop_table(me, DEFAULT_SQL_RESOURCES_TABLE);
                    155: 
                    156:        /* Create Resource table */
2.2       frystyk   157:        query = HTSQL_printf(buf, 1024,
                    158:                             "create table %s (uri %s primary key, length bigint unsigned not null, last_modified datetime, expires datetime, content_type char(32), charset char(32), content_encoding char(32), content_language char(32), title char(128))",
                    159:                             DEFAULT_SQL_RESOURCES_TABLE,
                    160:                             DEFAULT_SQL_KEY_TYPE);
                    161:        HTSQL_query(me->sql, query);
2.1       frystyk   162: 
                    163:        /* If we have to clear it out */
                    164:        if (flags & HTSQLLOG_CLEAR_RESOURCES_TABLE) 
                    165:            clear_table(me, DEFAULT_SQL_RESOURCES_TABLE);
                    166: 
                    167:        /* If we have to delete it first */
                    168:        if (flags & HTSQLLOG_DROP_LINKS_TABLE) 
                    169:            drop_table(me, DEFAULT_SQL_LINKS_TABLE);
                    170: 
                    171:        /* Create Link Relations table */
2.2       frystyk   172:        query = HTSQL_printf(buf, 1024,
                    173:                             "create table %s (source %s, destination %s, link_type char(32) not null, comment char(128), unique(source,destination,link_type))",
                    174:                             DEFAULT_SQL_LINKS_TABLE,
                    175:                             DEFAULT_SQL_KEY_TYPE,
                    176:                             DEFAULT_SQL_KEY_TYPE);
                    177:        HTSQL_query(me->sql, query);
2.1       frystyk   178: 
                    179:        /* If we have to clear it out */
                    180:        if (flags & HTSQLLOG_CLEAR_LINKS_TABLE) 
                    181:            clear_table(me, DEFAULT_SQL_LINKS_TABLE);
                    182: 
2.2       frystyk   183:        /* All done */
2.1       frystyk   184:        return YES;     
                    185:     }
                    186:     return NO;
                    187: }
                    188: 
                    189: /*     Open a connection
                    190: **     -----------------
                    191: **     Returns YES if OK, NO on error
                    192: */
2.2       frystyk   193: PUBLIC HTSQLLog * HTSQLLog_open (const char *  host,
                    194:                                 const char *   user,
                    195:                                 const char *   pw,
                    196:                                 const char *   db,
                    197:                                 HTSQLLogFlags  flags)
                    198: {
                    199:     HTSQLLog * me = NULL;
                    200:     if (!host || !user || !pw || !db) {
2.3       frystyk   201:        HTTRACE(SQL_TRACE, "SQLLog...... Missing SQLLog host, user, password, or db\n");
2.1       frystyk   202:        return NULL;
                    203:     }
                    204:     if ((me = (HTSQLLog *) HT_CALLOC(1, sizeof(HTSQLLog))) == NULL)
                    205:         HT_OUTOFMEM("HTSQLLog_open");
2.2       frystyk   206:     if ((me->sql = HTSQL_new(host, user, pw, 0)) != NULL &&
                    207:        HTSQL_connect(me->sql) == YES && HTSQL_selectDB(me->sql, db) == YES) {
2.1       frystyk   208: 
2.2       frystyk   209:        /* Make sure we have the right set of tables */
                    210:        createTables(me, flags);
                    211: 
                    212:        me->flags = flags;
                    213:     } else {
                    214:        HTSQL_delete(me->sql);
2.1       frystyk   215:        HT_FREE(me);
                    216:     }
                    217:     return me;
                    218: }
                    219: 
                    220: /*     Close connection
                    221: **     ----------------
                    222: **     Returns YES if OK, NO on error
                    223: */
                    224: PUBLIC BOOL HTSQLLog_close (HTSQLLog * me)
                    225: {
2.2       frystyk   226:     if (me) {
                    227:        if (me->sql) HTSQL_close(me->sql);
2.1       frystyk   228:        HT_FREE(me->relative);
                    229:        HT_FREE(me);
                    230:        return YES;
                    231:     }
                    232:     return NO;
                    233: }
                    234: 
                    235: PUBLIC BOOL HTSQLLog_clearTables (HTSQLLog * me)
                    236: {
2.2       frystyk   237:     if (me && me->sql) {
2.1       frystyk   238: 
                    239:        /* ... */
                    240: 
                    241:        return YES;
                    242:     }
                    243:     return NO;
                    244: }
                    245: 
                    246: PUBLIC BOOL HTSQLLog_makeRelativeTo (HTSQLLog * me, const char * relative)
                    247: {
                    248:     if (me) {
                    249:        StrAllocCopy(me->relative, relative);
                    250:        return YES;
                    251:     }
                    252:     return NO;
                    253: }
                    254: 
                    255: PUBLIC int HTSQLLog_accessCount (HTSQLLog * me)
                    256: {
                    257:     return me ? me->accesses : -1;
                    258: }
                    259: 
                    260: PUBLIC BOOL HTSQLLog_addURI (HTSQLLog * me, const char * uri)
                    261: {
2.2       frystyk   262:     return (me && me->sql && (add_uri(me, uri)>=0));
2.1       frystyk   263: }
                    264: 
                    265: PUBLIC BOOL HTSQLLog_addLinkRelationship (HTSQLLog * me,
                    266:                                          const char * src_uri,
                    267:                                          const char * dst_uri,
                    268:                                          const char * link_type,
                    269:                                          const char * comment)
                    270: {
                    271:     if (src_uri && dst_uri) {
                    272:        int srcidx = add_uri(me, src_uri);
                    273:        int dstidx = add_uri(me, dst_uri);
                    274:        return add_linktype(me, srcidx, dstidx, link_type, comment);
                    275:     }
                    276:     return NO;
                    277: }
                    278: 
                    279: PUBLIC BOOL HTSQLLog_addEntry (HTSQLLog * me, HTRequest * request, int status)
                    280: {
2.2       frystyk   281:     if (me && me->sql) {
2.1       frystyk   282:        HTParentAnchor * anchor = HTRequest_anchor(request);
                    283:        HTParentAnchor * parent_anchor = HTRequest_parent(request);
                    284:        char * uri = HTAnchor_address((HTAnchor *) anchor);
                    285:        int index = 0;
                    286:        char buf[512];
                    287:        char * query = NULL;
                    288: 
                    289:        /* Insert into the URI table */
2.2       frystyk   290:        if ((index = add_uri(me, uri)) < 0) {
                    291:            HT_FREE(uri);
                    292:            return NO;
                    293:        }
2.1       frystyk   294: 
                    295:        /* Insert into the request table */
2.2       frystyk   296:        query = HTSQL_printf(buf, 512, "replace into %s values (%u,%S,%u,%T,%T)",
                    297:                             DEFAULT_SQL_REQUESTS_TABLE,
                    298:                             index,
                    299:                             HTMethod_name(HTRequest_method(request)),
                    300:                             abs(status),
                    301:                             HTRequest_date(request),
                    302:                             HTAnchor_date(anchor));
                    303:        if (HTSQL_query(me->sql, query) != YES) {
                    304:            HT_FREE(uri);
2.1       frystyk   305:            return NO;
                    306:        }
                    307:        /* Insert into the resource table */
                    308:        {
                    309:            HTList * encodings = HTAnchor_encoding(anchor);
                    310:            HTList * languages = HTAnchor_language(anchor);
                    311:            HTFormat format = HTAnchor_format(anchor);
                    312:            HTCharset charset = HTAnchor_charset(anchor);
                    313:            HTEncoding encoding = encodings ? HTList_firstObject(encodings) : NULL;
                    314:            HTLanguage language = languages ? HTList_firstObject(languages) : NULL;
2.2       frystyk   315:            query = HTSQL_printf(buf, 512, "replace into %s values (%u,%l,%T,%T,%S,%S,%S,%S,%S)",
                    316:                                 DEFAULT_SQL_RESOURCES_TABLE,
                    317:                                 index,
                    318:                                 HTAnchor_length(anchor),
                    319:                                 HTAnchor_lastModified(anchor),
                    320:                                 HTAnchor_expires(anchor),
                    321:                                 format != WWW_UNKNOWN ? HTAtom_name(format) : NULL,
                    322:                                 charset ? HTAtom_name(charset) : NULL,
                    323:                                 encoding ? HTAtom_name(encoding) : NULL,
                    324:                                 language ? HTAtom_name(language) : NULL,
                    325:                                 HTAnchor_title(anchor));
                    326:            if (HTSQL_query(me->sql, query) != YES) {
                    327:                HT_FREE(uri);
2.1       frystyk   328:                return NO;
                    329:            }
                    330:        }
                    331: 
                    332:        /* Insert into the relationship table */
                    333:        if (parent_anchor) {
                    334:            char * parent = HTAnchor_address((HTAnchor *) parent_anchor);
                    335:            if (uri && parent && *parent) {
                    336:                int srcidx = add_uri(me, parent);
                    337:                add_linktype(me, srcidx, index, "referer", NULL);
                    338:            }
                    339:            HT_FREE(parent);
                    340:        }
                    341: 
                    342:        /* Count one more access */
                    343:        me->accesses++;
                    344: 
                    345:        HT_FREE(uri);
                    346:        return YES;
                    347:     }
                    348:     return NO;
                    349: }
                    350: 
                    351: 

Webmaster