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

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.2     ! frystyk     6: **     @(#) $Id: HTSQLLog.c,v 2.1 1998/05/04 19:37:19 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.2     ! frystyk    20: #include <mysql/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) {
        !           201:        if (SQL_TRACE)
        !           202:            HTTrace("SQLLog...... Missing SQLLog host, user, password, or db\n");
2.1       frystyk   203:        return NULL;
                    204:     }
                    205:     if ((me = (HTSQLLog *) HT_CALLOC(1, sizeof(HTSQLLog))) == NULL)
                    206:         HT_OUTOFMEM("HTSQLLog_open");
2.2     ! frystyk   207:     if ((me->sql = HTSQL_new(host, user, pw, 0)) != NULL &&
        !           208:        HTSQL_connect(me->sql) == YES && HTSQL_selectDB(me->sql, db) == YES) {
2.1       frystyk   209: 
2.2     ! frystyk   210:        /* Make sure we have the right set of tables */
        !           211:        createTables(me, flags);
        !           212: 
        !           213:        me->flags = flags;
        !           214:     } else {
        !           215:        HTSQL_delete(me->sql);
2.1       frystyk   216:        HT_FREE(me);
                    217:     }
                    218:     return me;
                    219: }
                    220: 
                    221: /*     Close connection
                    222: **     ----------------
                    223: **     Returns YES if OK, NO on error
                    224: */
                    225: PUBLIC BOOL HTSQLLog_close (HTSQLLog * me)
                    226: {
2.2     ! frystyk   227:     if (me) {
        !           228:        if (me->sql) HTSQL_close(me->sql);
2.1       frystyk   229:        HT_FREE(me->relative);
                    230:        HT_FREE(me);
                    231:        return YES;
                    232:     }
                    233:     return NO;
                    234: }
                    235: 
                    236: PUBLIC BOOL HTSQLLog_clearTables (HTSQLLog * me)
                    237: {
2.2     ! frystyk   238:     if (me && me->sql) {
2.1       frystyk   239: 
                    240:        /* ... */
                    241: 
                    242:        return YES;
                    243:     }
                    244:     return NO;
                    245: }
                    246: 
                    247: PUBLIC BOOL HTSQLLog_makeRelativeTo (HTSQLLog * me, const char * relative)
                    248: {
                    249:     if (me) {
                    250:        StrAllocCopy(me->relative, relative);
                    251:        return YES;
                    252:     }
                    253:     return NO;
                    254: }
                    255: 
                    256: PUBLIC int HTSQLLog_accessCount (HTSQLLog * me)
                    257: {
                    258:     return me ? me->accesses : -1;
                    259: }
                    260: 
                    261: PUBLIC BOOL HTSQLLog_addURI (HTSQLLog * me, const char * uri)
                    262: {
2.2     ! frystyk   263:     return (me && me->sql && (add_uri(me, uri)>=0));
2.1       frystyk   264: }
                    265: 
                    266: PUBLIC BOOL HTSQLLog_addLinkRelationship (HTSQLLog * me,
                    267:                                          const char * src_uri,
                    268:                                          const char * dst_uri,
                    269:                                          const char * link_type,
                    270:                                          const char * comment)
                    271: {
                    272:     if (src_uri && dst_uri) {
                    273:        int srcidx = add_uri(me, src_uri);
                    274:        int dstidx = add_uri(me, dst_uri);
                    275:        return add_linktype(me, srcidx, dstidx, link_type, comment);
                    276:     }
                    277:     return NO;
                    278: }
                    279: 
                    280: PUBLIC BOOL HTSQLLog_addEntry (HTSQLLog * me, HTRequest * request, int status)
                    281: {
2.2     ! frystyk   282:     if (me && me->sql) {
2.1       frystyk   283:        HTParentAnchor * anchor = HTRequest_anchor(request);
                    284:        HTParentAnchor * parent_anchor = HTRequest_parent(request);
                    285:        char * uri = HTAnchor_address((HTAnchor *) anchor);
                    286:        int index = 0;
                    287:        char buf[512];
                    288:        char * query = NULL;
                    289: 
                    290:        /* Insert into the URI table */
2.2     ! frystyk   291:        if ((index = add_uri(me, uri)) < 0) {
        !           292:            HT_FREE(uri);
        !           293:            return NO;
        !           294:        }
2.1       frystyk   295: 
                    296:        /* Insert into the request table */
2.2     ! frystyk   297:        query = HTSQL_printf(buf, 512, "replace into %s values (%u,%S,%u,%T,%T)",
        !           298:                             DEFAULT_SQL_REQUESTS_TABLE,
        !           299:                             index,
        !           300:                             HTMethod_name(HTRequest_method(request)),
        !           301:                             abs(status),
        !           302:                             HTRequest_date(request),
        !           303:                             HTAnchor_date(anchor));
        !           304:        if (HTSQL_query(me->sql, query) != YES) {
        !           305:            HT_FREE(uri);
2.1       frystyk   306:            return NO;
                    307:        }
                    308:        /* Insert into the resource table */
                    309:        {
                    310:            HTList * encodings = HTAnchor_encoding(anchor);
                    311:            HTList * languages = HTAnchor_language(anchor);
                    312:            HTFormat format = HTAnchor_format(anchor);
                    313:            HTCharset charset = HTAnchor_charset(anchor);
                    314:            HTEncoding encoding = encodings ? HTList_firstObject(encodings) : NULL;
                    315:            HTLanguage language = languages ? HTList_firstObject(languages) : NULL;
2.2     ! frystyk   316:            query = HTSQL_printf(buf, 512, "replace into %s values (%u,%l,%T,%T,%S,%S,%S,%S,%S)",
        !           317:                                 DEFAULT_SQL_RESOURCES_TABLE,
        !           318:                                 index,
        !           319:                                 HTAnchor_length(anchor),
        !           320:                                 HTAnchor_lastModified(anchor),
        !           321:                                 HTAnchor_expires(anchor),
        !           322:                                 format != WWW_UNKNOWN ? HTAtom_name(format) : NULL,
        !           323:                                 charset ? HTAtom_name(charset) : NULL,
        !           324:                                 encoding ? HTAtom_name(encoding) : NULL,
        !           325:                                 language ? HTAtom_name(language) : NULL,
        !           326:                                 HTAnchor_title(anchor));
        !           327:            if (HTSQL_query(me->sql, query) != YES) {
        !           328:                HT_FREE(uri);
2.1       frystyk   329:                return NO;
                    330:            }
                    331:        }
                    332: 
                    333:        /* Insert into the relationship table */
                    334:        if (parent_anchor) {
                    335:            char * parent = HTAnchor_address((HTAnchor *) parent_anchor);
                    336:            if (uri && parent && *parent) {
                    337:                int srcidx = add_uri(me, parent);
                    338:                add_linktype(me, srcidx, index, "referer", NULL);
                    339:            }
                    340:            HT_FREE(parent);
                    341:        }
                    342: 
                    343:        /* Count one more access */
                    344:        me->accesses++;
                    345: 
                    346:        HT_FREE(uri);
                    347:        return YES;
                    348:     }
                    349:     return NO;
                    350: }
                    351: 
                    352: 

Webmaster