Changeset 6263

Show
Ignore:
Timestamp:
12/28/99 19:07:08 (9 years ago)
Author:
ab
Message:

Modified Files:

midgard/lib/midgard.c midgard/lib/midgard.h
midgard/php/functions/midgard.c

Changes for supporting 'named' functions

Added Files:

midgard/proposals/new-functions

Information about added 'named' functions

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/src/core/midgard/midgard.c

    r6243 r6263  
    2323#include "internal.h" 
    2424#include "defaults.h" 
     25#if HAVE_CRYPT_H 
     26#include <crypt.h> 
     27#else 
     28#define _XOPEN_SOURCE 
     29#include <unistd.h> 
     30#endif 
    2531#include <stdlib.h> 
    2632#include <string.h> 
    2733#include <stdio.h> 
    28 #define __USE_XOPEN  /* to get crypt */ 
    29 #include <unistd.h> 
    30  
    31 const char *midgard_version() 
     34 
     35const char *mgd_version() 
    3236{ 
    3337        return VERSION; 
    3438} 
    3539 
    36 /* ODBC support functions */ 
    37  
    38 int  _midgard_execute_statement(Midgard *midgard, const char *sql) 
    39 
    40         SQLRETURN rv; 
    41         g_assert (midgard); 
    42  
    43         rv = SQLExecDirect(midgard->statement, (char *) sql, SQL_NTS); 
    44         if (rv != SQL_SUCCESS && rv != SQL_SUCCESS_WITH_INFO) 
    45                 return 0; 
    46  
    47         return 1; 
    48 
    49  
    50 int _midgard_fetch(Midgard *midgard) 
    51 
    52         SQLRETURN rv; 
    53         g_assert (midgard); 
    54         g_return_val_if_fail (midgard->statement, 0); 
    55  
    56         rv = SQLFetch(midgard->statement); 
    57         if (rv != SQL_SUCCESS && rv != SQL_SUCCESS_WITH_INFO) 
    58                 return 0; 
    59  
    60         return 1; 
    61 
    62   
    63 void _midgard_clear_statement(Midgard *midgard) 
    64 
    65         g_assert (midgard); 
    66         g_return_if_fail (midgard->statement); 
    67          
    68         SQLFreeStmt(midgard->statement, SQL_CLOSE); 
    69         SQLFreeStmt(midgard->statement, SQL_RESET_PARAMS); 
    70         SQLFreeStmt(midgard->statement, SQL_UNBIND); 
    71 
    72  
    73 int _midgard_result_columns(Midgard *midgard) 
    74 
    75         SQLRETURN rv; 
    76         SQLSMALLINT count; 
    77         g_assert (midgard); 
    78  
    79         rv = SQLNumResultCols(midgard->statement, &count); 
    80         if (rv != SQL_SUCCESS && rv != SQL_SUCCESS_WITH_INFO) 
    81                 return 0; 
    82  
    83         return count; 
    84 
    85  
    86 #define DATALEN 4096 
    87 static char databuf[DATALEN]; 
    88  
    89 const char *_midgard_column_name(Midgard *midgard, int pos) 
    90 
    91         SQLSMALLINT ind, a, c, d; 
    92         SQLUINTEGER b; 
    93         SQLCHAR *val; 
    94         SQLRETURN rv; 
    95  
    96         rv = SQLDescribeCol(midgard->statement, pos, 
    97                             databuf, DATALEN, &ind, &a, &b, &c, &d); 
    98         if (rv != SQL_SUCCESS && rv != SQL_SUCCESS_WITH_INFO) 
     40midgard *mgd_connect(const char *database, 
     41                     const char *username, const char *password) 
     42
     43    midgard *mgd; 
     44 
     45    /* create midgard handle */ 
     46    mgd = (midgard *) malloc(sizeof(struct midgard)); 
     47    if (!mgd) return NULL; 
     48 
     49    mgd->res = NULL; 
     50    mgd->pool = mgd_alloc_pool(); 
     51    if (!mgd->pool) { free(mgd); return NULL; } 
     52    mgd->tmp = mgd_alloc_pool(); 
     53    if (!mgd->tmp) { mgd_free_pool(mgd->pool); free(mgd); return NULL; } 
     54 
     55    mgd->user = mgd->admin = 0; 
     56    mgd->member = NULL; 
     57    mgd->username = mgd->name = NULL; 
     58 
     59    /* use default values if none specified */ 
     60    if (!username) username = MGD_MYSQL_USERNAME; 
     61    if (!password) password = MGD_MYSQL_PASSWORD; 
     62    if (!database) database = MGD_MYSQL_DATABASE; 
     63 
     64    /* create mysql connection handle */ 
     65    mgd->mysql = mysql_init(NULL); 
     66    if (!mgd->mysql) { 
     67            mgd_free_pool(mgd->tmp);  
     68            mgd_free_pool(mgd->pool); 
     69            free(mgd); 
     70            return NULL; 
     71    } 
     72 
     73    /* connect to sql server */ 
     74    mysql_real_connect(mgd->mysql, MGD_MYSQL_HOST, 
     75                       username, password, database, 0, NULL, 0); 
     76 
     77    return mgd; 
     78
     79 
     80void mgd_close(midgard *mgd) 
     81
     82    assert(mgd); 
     83    mgd_clear(mgd); 
     84    if (mgd->mysql) mysql_close(mgd->mysql); 
     85    mgd_free_pool(mgd->tmp); 
     86    mgd_free_pool(mgd->pool); 
     87    free(mgd); 
     88
     89 
     90int mgd_auth(midgard *mgd, const char *username, const char *password) 
     91
     92    midgard_res *res; 
     93    int i; 
     94    const char *cipher, *passwd; 
     95    assert(mgd && mgd->mysql);     
     96 
     97    /* Clear user information and release resources */ 
     98    mgd_clear(mgd); 
     99 
     100    /* Authenticate and get user information */ 
     101    /* TODO: Should this be moved to the card module? */ 
     102    if (!username || !*username) return 1; /* anonymous */ 
     103    res = mgd_select(mgd, "id,password", "person", "username=$q", NULL, 
     104                     username); 
     105    if (!res) return 0;       /* username not found */ 
     106    while (!mgd->user && mgd_fetch(res)) { 
     107            passwd = mgd_colvalue(res, 1); 
     108            if (passwd[0] == '*' && passwd[1] == '*') { 
     109                    passwd += 2; 
     110                    cipher = password; 
     111            } else 
     112                    cipher = crypt(password, passwd); 
     113            if (!strcmp(cipher, passwd)) 
     114                    mgd->user = atoi(mgd_colvalue(res, 0)); 
     115    } 
     116    mgd_release(res); 
     117    if (!mgd->user) return 0; /* password not found */ 
     118 
     119    /* Get group information */ 
     120    res = mgd_select(mgd, "gid", "member", "uid=$i", NULL, mgd->user); 
     121    if (res) { 
     122        mgd->member = (int *) malloc(sizeof(int) * (mgd_rows(res) + 1)); 
     123        i = 0; 
     124        while (mgd_fetch(res)) 
     125            if ((mgd->member[i] = mgd_sql2id(res,0)) != 0) 
     126                i++; 
     127            else 
     128                mgd->admin = 1; 
     129        mgd->member[i] = 0; 
     130        mgd_release(res); 
     131    } 
     132 
     133    return mgd->user; 
     134
     135 
     136void mgd_clear(midgard *mgd) 
     137
     138    assert(mgd); 
     139 
     140    /* clear user information */ 
     141    mgd->user = mgd->admin = 0; 
     142    mgd->username = NULL; 
     143    mgd->name = NULL; 
     144    mgd->member = NULL; 
     145 
     146    /* clear resources reserved */ 
     147    while (mgd->res) 
     148        mgd_release(mgd->res); 
     149 
     150    mgd_clear_pool(mgd->pool); 
     151
     152 
     153int mgd_errno(midgard *mgd) 
     154
     155    assert(mgd); 
     156    return mysql_errno(mgd->mysql); 
     157
     158 
     159const char *mgd_error(midgard *mgd) 
     160
     161    assert(mgd); 
     162    return mysql_error(mgd->mysql); 
     163
     164 
     165int mgd_user(midgard *mgd) 
     166
     167    assert(mgd); 
     168    return mgd->user; 
     169
     170 
     171int mgd_isauser(midgard *mgd) 
     172
     173    assert(mgd); 
     174    return mgd->user != 0; 
     175
     176 
     177int mgd_isadmin(midgard *mgd) 
     178
     179    assert(mgd); 
     180    return mgd->admin != 0; 
     181
     182 
     183int mgd_isuser(midgard *mgd, int user) 
     184
     185    assert(mgd); 
     186    return mgd->user == user; 
     187
     188 
     189int mgd_ismember(midgard *mgd, int group) 
     190
     191    int i; 
     192    assert(mgd); 
     193    if (!mgd->member) return 0; 
     194    for (i = 0; mgd->member[i]; i++) 
     195        if (mgd->member[i] == group) return 1; 
     196    return 0; 
     197
     198 
     199int *mgd_groups(midgard *mgd) 
     200
     201        return mgd->member; 
     202
     203 
     204midgard_res *mgd_query(midgard *mgd, const char *query, ...) 
     205
     206    midgard_res *res; 
     207    va_list args; 
     208    va_start(args, query); 
     209    res = mgd_vquery(mgd, query, args); 
     210    va_end(args); 
     211    return res; 
     212
     213 
     214midgard_res *mgd_vquery(midgard *mgd, const char *query, va_list args) 
     215
     216    midgard_res *res; 
     217    midgard_pool *pool; 
     218    MYSQL_RES *mres; 
     219    int rv; 
     220    const char *fquery; 
     221    assert(mgd && mgd->mysql); 
     222    assert(query); 
     223 
     224    /* format and send query */ 
     225    pool = mgd_alloc_pool(); 
     226    if (!pool) return NULL; 
     227    fquery = mgd_vformat(pool, query, args); 
     228    if (!fquery) { mgd_free_pool(pool); return NULL; } 
     229    rv = mysql_query(mgd->mysql, fquery); 
     230    mgd_free_pool(pool); 
     231    if (rv != 0) return NULL; 
     232 
     233    /* get results */ 
     234    mres = mysql_store_result(mgd->mysql); 
     235    if (!mres) return NULL; 
     236    if (mysql_num_rows(mres) == 0) { mysql_free_result(mres); return NULL; } 
     237    /* create result handle */ 
     238    res = (midgard_res *) malloc(sizeof(struct midgard_res)); 
     239    if (!res) { mysql_free_result(mres); return NULL; } 
     240    res->pool = mgd_alloc_pool(); 
     241    if (!res->pool) { free(res); mysql_free_result(mres); return NULL; } 
     242    res->mgd = mgd; 
     243    res->res = mres; 
     244    res->row = NULL; 
     245    res->rown = 0; 
     246    res->rows = mysql_num_rows(mres); 
     247    res->cols = mysql_num_fields(mres); 
     248 
     249    /* insert into result chain */ 
     250    if (mgd->res) mgd->res->prev = res; 
     251    res->prev = NULL; 
     252    res->next = mgd->res; 
     253    mgd->res = res; 
     254     
     255    return res; 
     256
     257 
     258midgard_res *mgd_select(midgard *mgd, 
     259                        const char *fields, const char *from, 
     260                        const char *where, const char *sort, ...) 
     261
     262    midgard_res *res; 
     263    va_list args; 
     264    va_start(args, sort); 
     265    res = mgd_vselect(mgd, fields, from, where, sort, args); 
     266    va_end(args); 
     267    return res; 
     268
     269 
     270midgard_res *mgd_vselect(midgard *mgd, 
     271                         const char *fields, const char *from, 
     272                         const char *where, const char *sort, va_list args) 
     273
     274    midgard_res *res; 
     275    const char *query; 
     276    assert(fields && from); 
     277 
     278    /* format query */ 
     279    if (where) 
     280        if (sort) 
     281            query = mgd_format(mgd->tmp, 
     282                               "SELECT $s FROM $s WHERE $s ORDER BY $s", 
     283                               fields, from, where, sort); 
     284        else 
     285            query = mgd_format(mgd->tmp, "SELECT $s FROM $s WHERE $s", 
     286                               fields, from, where); 
     287    else 
     288        if (sort) 
     289            query = mgd_format(mgd->tmp, "SELECT $s FROM $s ORDER BY $s", 
     290                               fields, from, sort); 
     291        else 
     292            query = mgd_format(mgd->tmp, "SELECT $s FROM $s", 
     293                               fields, from); 
     294    if (!query) return NULL; 
     295 
     296    /* execute query */ 
     297    res = mgd_vquery(mgd, query, args); 
     298 
     299    mgd_clear_pool(mgd->tmp); 
     300    return res; 
     301
     302 
     303midgard_res *mgd_record(midgard *mgd, 
     304                        const char *fields, const char *table, int id) 
     305
     306    midgard_res *res; 
     307    const char *query; 
     308 
     309    /* format query */ 
     310    query = mgd_format(mgd->tmp, "SELECT $s FROM $s WHERE id=$i", 
     311                       fields, table, id); 
     312    if (!query) return NULL; 
     313 
     314    /* execute query */ 
     315    res = mgd_query(mgd, query); 
     316 
     317    mgd_clear_pool(mgd->tmp); 
     318    return res; 
     319
     320 
     321midgard_res *mgd_record_by_name(midgard *mgd, 
     322                        const char *fields, const char *table,  
     323                        const char* idfield, int id, const char* name) 
     324
     325    midgard_res *res; 
     326    const char *query; 
     327 
     328    /* format query */ 
     329    query = mgd_format(mgd->tmp, "SELECT $s FROM $s WHERE $s=$i AND name='$s'", 
     330                       fields, table, idfield, id, name); 
     331    if (!query) return NULL; 
     332 
     333    /* execute query */ 
     334    res = mgd_query(mgd, query); 
     335 
     336    mgd_clear_pool(mgd->tmp); 
     337    return res; 
     338
     339 
     340midgard_res *mgd_record_by_name2(midgard *mgd, 
     341                        const char *fields, const char *table,  
     342                        const char *firstfield, const char *first,  
     343                        const char *secondfield, const char *second) 
     344
     345    midgard_res *res; 
     346    const char *query; 
     347 
     348    /* format query */ 
     349    query = mgd_format(mgd->tmp, "SELECT $s FROM $s WHERE $s='$s' AND $s='$s'", 
     350                       fields, table, firstfield, first, secondfield, second); 
     351    if (!query) return NULL; 
     352 
     353    /* execute query */ 
     354    res = mgd_query(mgd, query); 
     355 
     356    mgd_clear_pool(mgd->tmp); 
     357    return res; 
     358
     359 
     360midgard_res *mgd_record_by_name_only(midgard *mgd, 
     361                        const char *fields, const char *table,  
     362                        const char* name) 
     363
     364    midgard_res *res; 
     365    const char *query; 
     366 
     367    /* format query */ 
     368    query = mgd_format(mgd->tmp, "SELECT $s FROM $s WHERE name='$s'", 
     369                       fields, table, name); 
     370    if (!query) return NULL; 
     371 
     372    /* execute query */ 
     373    res = mgd_query(mgd, query); 
     374 
     375    mgd_clear_pool(mgd->tmp); 
     376    return res; 
     377
     378 
     379int mgd_idfield(midgard *mgd, const char *field, const char *table, int id) 
     380
     381    midgard_res *res; 
     382    int rv; 
     383 
     384    /* get record field */ 
     385    res = mgd_record(mgd, field, table, id); 
     386    if (!res) return 0; 
     387 
     388    /* get id value */ 
     389    if (mgd_fetch(res)) 
     390        rv = mgd_sql2id(res, 0); 
     391    else 
     392        rv = 0; 
     393    mgd_release(res); 
     394 
     395    return rv; 
     396
     397 
     398int mgd_exists(midgard *mgd, const char *from, const char *where, ...) 
     399
     400    midgard_res *res; 
     401    const char *query; 
     402    va_list args; 
     403    int rv = 0; 
     404 
     405    /* format query */ 
     406    if (strchr(from, ',')) 
     407      query = mgd_format(mgd->tmp, "SELECT 1 FROM $s WHERE $s", from, where); 
     408    else 
     409      query = mgd_format(mgd->tmp, "SELECT id FROM $s WHERE $s", from, where); 
     410    if (!query) return 0; 
     411 
     412    /* execute query */ 
     413    va_start(args, where); 
     414    res = mgd_vquery(mgd, query, args); 
     415    va_end(args); 
     416 
     417    mgd_clear_pool(mgd->tmp); 
     418    if (!res) return 0; 
     419    if (mgd_fetch(res)) 
     420            rv = atoi(mgd_colvalue(res, 0)); 
     421 
     422    mgd_release(res); 
     423    return rv; 
     424
     425 
     426int mgd_fetch(midgard_res *res) 
     427
     428    assert(res && res->res); 
     429    if (res->row) res->rown++; 
     430    res->row = mysql_fetch_row(res->res); 
     431    if (!res->row) return 0; 
     432    return 1; 
     433
     434 
     435void mgd_release(midgard_res *res) 
     436
     437    assert(res && res->res); 
     438    mysql_free_result(res->res); 
     439    mgd_free_pool(res->pool); 
     440    if (res->next) res->next->prev = res->prev; 
     441    if (res->prev) res->prev->next = res->next; else res->mgd->res = res->next; 
     442    free(res); 
     443
     444 
     445int mgd_rows(midgard_res *res) 
     446
     447    assert(res); 
     448    return res->rows; 
     449
     450 
     451int mgd_cols(midgard_res *res) 
     452
     453    assert(res); 
     454    return res->cols; 
     455
     456 
     457const char *mgd_colname(midgard_res *res, int i) 
     458
     459        assert(res && res->res); 
     460        if (0 <= i && i < res->cols) 
     461#if MYSQL_VERSION_ID > 32225 
     462                return mysql_fetch_field_direct(res->res, i)->name; 
     463#else 
     464                return mysql_fetch_field_direct(res->res, i).name; 
     465#endif 
     466        else 
    99467                return NULL; 
    100         if (ind == SQL_NULL_DATA || ind == SQL_NO_TOTAL) 
    101                 return NULL; 
    102          
    103         val = (char *) malloc(ind+1); 
    104         if (!val) return NULL; 
    105         strcpy(val, databuf); 
    106  
    107         return val; 
    108 
    109  
    110 const char *_midgard_column_value(Midgard *midgard, int pos) 
    111 
    112         SQLINTEGER ind; 
    113         char *val = NULL; 
    114         int len = 0, siz = 0; 
    115         SQLRETURN rv; 
    116  
    117         do { 
    118                 rv = SQLGetData(midgard->statement, pos, SQL_C_CHAR, 
    119                                 databuf, DATALEN, &ind); 
    120                 if ((rv != SQL_SUCCESS && rv != SQL_SUCCESS_WITH_INFO) 
    121                     || ind == SQL_NULL_DATA) { 
    122                         if (val) free(val); 
    123                         return NULL; 
    124                 } 
    125                 if (siz == 0) { 
    126                         siz = (ind < DATALEN && ind != SQL_NO_TOTAL) 
    127                                 ? ind+1 : DATALEN; 
    128                         len = siz-1; 
    129                         val = (char *) malloc(siz); 
    130                         if (!val) return NULL; 
    131                         memcpy(val, databuf, len); 
    132                         val[len] = '\0'; 
    133                 } else { 
    134                         siz += (ind < DATALEN && ind != SQL_NO_TOTAL) 
    135                                 ? ind : DATALEN - 1; 
    136                         val = (char *) realloc(val, siz); 
    137                         if (!val) return NULL; 
    138                         memcpy(val+len, databuf, siz-len); 
    139                         len = siz-1; 
    140                         val[len] = '\0'; 
    141                 } 
    142         } while (ind >= DATALEN || ind == SQL_NO_TOTAL); 
    143  
    144         return val; 
    145 
    146  
    147 int _midgard_bind_parameter_int(Midgard *midgard, int pos, int *val) 
    148 
    149         SQLRETURN rv; 
    150         g_assert (midgard); 
    151  
    152         rv = SQLBindParameter(midgard->statement, pos, SQL_PARAM_INPUT, 
    153                               SQL_C_SLONG, SQL_INTEGER, 0, 0, val, 0, NULL); 
    154         if (rv != SQL_SUCCESS && rv != SQL_SUCCESS_WITH_INFO) 
    155                 return 0; 
    156  
    157         return 1; 
    158 
    159  
    160 int _midgard_bind_parameter_str(Midgard *midgard, int pos, const char *str) 
    161 
    162         SQLRETURN rv; 
    163         int len = strlen(str); 
    164         g_assert (midgard); 
    165  
    166         rv = SQLBindParameter(midgard->statement, pos, SQL_PARAM_INPUT, 
    167                               SQL_C_CHAR, SQL_CHAR, len, 0, 
    168                               (SQLCHAR *) str, len, NULL); 
    169         if (rv != SQL_SUCCESS && rv != SQL_SUCCESS_WITH_INFO) 
    170                 return 0; 
    171  
    172         return 1; 
    173 
    174  
    175 int _midgard_bind_column_long(Midgard *midgard, int pos, long *val) 
    176 
    177         SQLRETURN rv; 
    178         g_assert (midgard); 
    179  
    180         rv = SQLBindCol(midgard->statement, pos, SQL_C_SLONG, val, 0, NULL); 
    181         if (rv != SQL_SUCCESS && rv != SQL_SUCCESS_WITH_INFO) 
    182                 return 0; 
    183  
    184         return 1; 
    185 
    186  
    187 int _midgard_bind_column_str(Midgard *midgard, int pos, char *str, int len) 
    188 
    189         SQLRETURN rv; 
    190         g_assert (midgard); 
    191  
    192         rv = SQLBindCol(midgard->statement, pos, SQL_C_CHAR, str, len, NULL); 
    193         if (rv != SQL_SUCCESS && rv != SQL_SUCCESS_WITH_INFO) 
    194                 return 0; 
    195  
    196         return 1; 
    197 
    198  
    199 Midgard * 
    200 midgard_handle_new () 
    201 
    202         Midgard *midgard = (Midgard *) g_malloc0 (sizeof(Midgard)); 
    203         if (!midgard) return NULL; 
    204  
    205         midgard->env = SQL_NULL_HENV; 
    206         midgard->dbc = SQL_NULL_HDBC; 
    207         midgard->statement = SQL_NULL_HSTMT; 
    208  
    209         return midgard; 
    210 
    211  
    212 gboolean 
    213 midgard_handle_free (Midgard *midgard) 
    214 
    215         g_return_val_if_fail (midgard, FALSE); 
    216         midgard_close (midgard); 
    217         g_free (midgard); 
    218         return TRUE; 
    219 
    220  
    221 gboolean 
    222 midgard_connected (Midgard *midgard) 
    223 
    224         g_return_val_if_fail (midgard, FALSE); 
    225         return (midgard->env != SQL_NULL_HENV 
    226                 && midgard->dbc != SQL_NULL_HDBC 
    227                 && midgard->statement != SQL_NULL_HSTMT); 
    228 
    229  
    230 gboolean 
    231 midgard_connect (Midgard *midgard, const char *database, 
    232                  const char *username, const char *password) 
    233 
    234         int rv; 
    235         g_return_val_if_fail (midgard, FALSE); 
    236  
    237         /* Make sure the connection is closed before opening a new one */ 
    238         midgard_close (midgard); 
    239  
    240         /* create ODBC environment handle */ 
    241         rv = SQLAllocEnv (&midgard->env); 
    242         if (rv != SQL_SUCCESS && rv != SQL_SUCCESS_WITH_INFO) { 
    243                 midgard->env = SQL_NULL_HENV; 
    244                 return FALSE; 
    245         } 
    246          
    247         /* create ODBC connection handle */ 
    248         rv = SQLAllocConnect (midgard->env, &midgard->dbc); 
    249         if (rv != SQL_SUCCESS && rv != SQL_SUCCESS_WITH_INFO) {  
    250                 SQLFreeEnv (midgard->env); 
    251                 midgard->env = SQL_NULL_HENV; 
    252                 midgard->dbc = SQL_NULL_HDBC; 
    253                 return FALSE; 
    254         } 
    255         
    256         /* connect to the Midgard database */ 
    257         if (!database) database = MIDGARD_DATABASE; 
    258         if (!username) username = MIDGARD_USERNAME; 
    259         if (!password) password = MIDGARD_PASSWORD; 
    260         rv = SQLConnect (midgard->dbc, 
    261                          (SQLCHAR *) database, SQL_NTS, 
    262                          (SQLCHAR *) username, SQL_NTS, 
    263                          (SQLCHAR *) password, SQL_NTS); 
    264         if (rv != SQL_SUCCESS && rv != SQL_SUCCESS_WITH_INFO) { 
    265                 SQLFreeConnect (midgard->dbc); 
    266                 SQLFreeEnv (midgard->env); 
    267                 midgard->env = SQL_NULL_HENV; 
    268                 midgard->dbc = SQL_NULL_HDBC; 
    269                 return FALSE; 
    270         } 
    271  
    272         /* create ODBC statement handle */ 
    273         rv = SQLAllocStmt (midgard->dbc, &midgard->statement); 
    274         if (rv != SQL_SUCCESS && rv != SQL_SUCCESS_WITH_INFO) {  
    275                 SQLDisconnect (midgard->dbc); 
    276                 SQLFreeConnect (midgard->dbc); 
    277                 SQLFreeEnv (midgard->env); 
    278                 midgard->env = SQL_NULL_HENV; 
    279                 midgard->dbc = SQL_NULL_HDBC; 
    280                 midgard->statement = SQL_NULL_HSTMT; 
    281                 return FALSE; 
    282         } 
    283  
    284         return TRUE; 
    285 
    286  
    287 gboolean midgard_close(Midgard *midgard) 
    288 
    289         g_return_val_if_fail (midgard, FALSE); 
    290  
    291         /* Clear caches and authentication information */ 
    292         midgard_clear(midgard); 
    293  
    294         /* Disconnect and free ODBC handles */ 
    295  
    296         if (midgard->statement != SQL_NULL_HSTMT) { 
    297                 SQLFreeStmt (midgard->statement, SQL_DROP); 
    298                 midgard->statement = SQL_NULL_HSTMT; 
    299         } 
    300  
    301         if (midgard->dbc != SQL_NULL_HDBC) { 
    302                 SQLDisconnect (midgard->dbc); 
    303                 SQLFreeConnect (midgard->dbc); 
    304                 midgard->dbc = SQL_NULL_HDBC; 
    305         } 
    306  
    307         if (midgard->env != SQL_NULL_HENV) { 
    308                 SQLFreeEnv (midgard->env); 
    309                 midgard->env = SQL_NULL_HENV; 
    310         } 
    311  
    312         return TRUE; 
    313 
    314  
    315 #define FINDUSER "SELECT id,password FROM person WHERE username=?" 
    316 #define FINDGRPS "SELECT gid FROM member WHERE uid=?" 
    317  
    318 gboolean 
    319 midgard_auth (Midgard *midgard, const char *username, const char *password) 
    320 
    321         int i, n; 
    322         long id; 
    323         char *cipher; 
    324         char pwd[16]; 
    325         g_assert (midgard); 
    326         g_return_val_if_fail (midgard_connected (midgard), FALSE); 
    327  
    328         /* Clear caches and authentication information */ 
    329         midgard_clear (midgard); 
    330          
    331         /* Authenticate and get user information */ 
    332         /* TODO: Should this be moved to the card module? */ 
    333         if (!username || !*username) return TRUE; /* anonymous */ 
    334  
    335         /* PART 1: Find the user with the given username and password. 
    336          * We search for a person record whose username field matches 
    337          * the given username and the password field contains the crypted 
    338          * password or the password field is of the form '**XXXX' where 
    339          * 'XXXX' is the given password in plain text. 
    340          */ 
    341         if (!_midgard_bind_parameter_str(midgard, 1, username) 
    342             || !_midgard_bind_column_long(midgard, 1, &id) 
    343             || !_midgard_bind_column_str(midgard, 2, pwd, sizeof(pwd)) 
    344             || !_midgard_execute_statement(midgard, FINDUSER)) { 
    345                 _midgard_clear_statement(midgard); 
    346                 return 0; 
    347         } 
    348  
    349         while (!midgard->user && _midgard_fetch(midgard)) { 
    350                 cipher = crypt(password, pwd); 
    351                 if (!strcmp(cipher, pwd) 
    352                     || (!strncmp(pwd, "**", 2) && !strcmp(password, pwd+2))) 
    353                         midgard->user = id; 
    354         } 
    355         _midgard_clear_statement(midgard); 
    356  
    357         /* PART 2: List the groups the user belongs to. 
    358          * If a member record with the gid field containing zero is found, 
    359          * then the user is administrator. 
    360          */ 
    361         if (!_midgard_bind_parameter_int(midgard, 1, &midgard->user) 
    362             || !_midgard_bind_column_long(midgard, 1, &id) 
    363             || !_midgard_execute_statement(midgard, FINDGRPS)) { 
    364                 _midgard_clear_statement(midgard); 
    365                 midgard->user = 0; 
    366                 return 0; 
    367         } 
    368  
    369         n = 16; i = 0; 
    370         midgard->member = (int *) malloc(sizeof(int) * n); 
    371         if (!midgard->member) { 
    372                 _midgard_clear_statement(midgard); 
    373                 midgard->user = 0; 
    374                 return 0; 
    375         } 
    376  
    377         while (_midgard_fetch(midgard)) 
    378                 if (id == 0) 
    379                         midgard->admin = 1; 
    380                 else { 
    381                         midgard->member[i++] = id; 
    382                         if (i == n) { 
    383                                 n *= 2; 
    384                                 midgard->member = (int *) 
    385                                         realloc(midgard->member, sizeof(int) * n); 
    386                                 if (!midgard->member) { 
    387                                         _midgard_clear_statement(midgard); 
    388                                         midgard->user = 0; 
    389                                         return 0; 
    390                                 } 
    391                         } 
    392                 } 
    393         _midgard_clear_statement(midgard); 
    394  
    395         return midgard->user; 
    396 
    397  
    398 gboolean 
    399 midgard_clear (Midgard *midgard) 
    400 
    401         g_return_val_if_fail (midgard, FALSE); 
    402          
    403         /* clear user information */ 
    404         midgard->user = midgard->admin = 0; 
    405         midgard->username = NULL; 
    406         midgard->name = NULL; 
    407         midgard->member = NULL; 
    408  
    409         return TRUE; 
    410 
    411  
    412 const char * 
    413 midgard_error(Midgard *midgard) 
    414 
    415         g_assert (midgard); 
    416         return ""; 
    417 
    418  
    419 MidgardID 
    420 midgard_user (Midgard *midgard) 
    421 
    422         g_return_val_if_fail (midgard, FALSE); 
    423         return midgard->user; 
    424 
    425  
    426 gboolean 
    427 midgard_isauser (Midgard *midgard) 
    428 
    429         g_return_val_if_fail (midgard, FALSE); 
    430         return midgard->user != 0; 
    431 
    432  
    433 gboolean 
    434 midgard_isadmin (Midgard *midgard) 
    435 
    436         g_return_val_if_fail (midgard, FALSE); 
    437         return midgard->admin != 0; 
    438 
    439  
    440 gboolean 
    441 midgard_isuser (Midgard *midgard, MidgardID user) 
    442 
    443         g_return_val_if_fail (midgard, FALSE); 
    444         return midgard->user == user; 
    445 
    446  
    447 gboolean 
    448 midgard_ismember(Midgard *midgard, MidgardID group) 
     468
     469 
     470const char *mgd_colvalue(midgard_res *res, int i) 
     471
     472    assert(res && res->row); 
     473    if (0 <= i && i < res->cols) 
     474        return res->row[i]; 
     475    else 
     476        return NULL; 
     477
     478 
     479const char *mgd_column(midgard_res *res, const char *name) 
    449480{ 
    450481        int i; 
    451         g_return_val_if_fail (midgard, FALSE); 
    452         if (!midgard->member) return FALSE; 
    453         for (i = 0; midgard->member[i]; i++) 
    454                 if (midgard->member[i] == group) return TRUE; 
    455         return FALSE; 
    456 
    457  
    458 int * 
    459 midgard_groups (Midgard *midgard) 
    460 
    461         g_return_val_if_fail (midgard, NULL); 
    462         return midgard->member; 
    463 
     482        for (i = 0; i < mgd_cols(res); i++) 
     483                if (strcmp(mgd_colname(res, i), name) == 0) 
     484                        return mgd_colvalue(res, i); 
     485        return NULL; 
     486
     487 
     488int mgd_exec(midgard *mgd, const char *command, ...) 
     489
     490    int rv; 
     491    va_list args; 
     492    va_start(args, command); 
     493    rv = mgd_vexec(mgd, command, args); 
     494    va_end(args); 
     495    return rv; 
     496
     497 
     498int mgd_vexec(midgard *mgd, const char *command, va_list args) 
     499
     500    int rv; 
     501    char *fcommand; 
     502    assert(mgd && mgd->mysql); 
     503    assert(command); 
     504 
     505    /* format and send command */ 
     506    fcommand = mgd_vformat(mgd->tmp, command, args); 
     507    if (!fcommand) return 0; 
     508    rv = mysql_query(mgd->mysql, fcommand); 
     509 
     510    mgd_clear_pool(mgd->tmp); 
     511    return rv ? 0 : 1; 
     512
     513 
     514 
     515int mgd_create(midgard *mgd, const char *table, 
     516               const char *fields, const char *values, ...) 
     517
     518    int id; 
     519    va_list args; 
     520    va_start(args, values); 
     521    id = mgd_vcreate(mgd, table, fields, values, args); 
     522    va_end(args); 
     523    return id; 
     524
     525 
     526int mgd_vcreate(midgard *mgd, const char *table, 
     527                const char *fields, const char *values, va_list args) 
     528
     529    const char *command; 
     530    int rv; 
     531 
     532    /* format command */ 
     533    command = mgd_format(mgd->tmp, 
     534                         "INSERT INTO $s ($s) VALUES ($s)", 
     535                         table, fields, values); 
     536    if (!command) return 0; 
     537 
     538    /* execute command */ 
     539    rv = mgd_vexec(mgd, command, args); 
     540 
     541    mgd_clear_pool(mgd->tmp); 
     542    return rv ? mysql_insert_id(mgd->mysql) : 0; 
     543
     544 
     545int mgd_update(midgard *mgd, const char *table, int id, 
     546               const char *fields, ...) 
     547
     548    int rv; 
     549    va_list args; 
     550    va_start(args, fields); 
     551    rv = mgd_vupdate(mgd, table, id, fields, args); 
     552    va_end(args); 
     553    return id; 
     554
     555 
     556int mgd_vupdate(midgard *mgd, const char *table, int id, 
     557                const char *fields, va_list args) 
     558
     559    const char *command; 
     560    int rv; 
     561 
     562    /* format command */ 
     563    command = mgd_format(mgd->tmp, 
     564                         "UPDATE $s SET $s WHERE id=$d", 
     565                         table, fields, id); 
     566    if (!command) return 0; 
     567 
     568    /* execute command */ 
     569    rv = mgd_vexec(mgd, command, args); 
     570 
     571    mgd_clear_pool(mgd->tmp); 
     572    return rv; 
     573
     574 
     575int mgd_delete(midgard *mgd, const char *table, int id) 
     576
     577    const char *command; 
     578    int rv; 
     579 
     580    /* format command */ 
     581    command = mgd_format(mgd->tmp, "DELETE FROM $s WHERE id=$d", table, id); 
     582    if (!command) return 0; 
     583 
     584    /* execute command */ 
     585    rv = mgd_exec(mgd, command); 
     586 
     587    mgd_clear_pool(mgd->tmp); 
     588    return rv; 
     589
     590 
     591int mgd_translate(const char *host, int port, const char *uri) 
     592
     593        return 0; 
     594
  • trunk/src/core/midgard/midgard.h

    r6245 r6263  
    2323#define MIDGARD_H 
    2424#include <stdarg.h> 
    25 #include <glib.h> 
     25#include <assert.h> 
    2626#include <time.h> 
    2727 
    28 typedef struct Midgard Midgard; 
     28typedef struct midgard midgard; 
    2929typedef struct midgard_res midgard_res; 
    3030typedef struct midgard_pool midgard_pool; 
    3131 
    32 typedef unsigned long int MidgardID; 
    33 typedef struct MidgardTable MidgardTable; 
    34 typedef struct MidgardList MidgardList; 
    35 typedef struct MidgardRecord MidgardRecord; 
     32#define MGD_STRUCT_STD_FIELDS \ 
     33  midgard_res *res; int restype; \ 
     34  int id, creator, revisor, revision; \ 
     35  time_t created, revised; 
    3636 
    37 typedef enum { 
    38         MIDGARD_ACCESS_READ, 
    39         MIDGARD_ACCESS_CREATE, 
    40         MIDGARD_ACCESS_UPDATE, 
    41         MIDGARD_ACCESS_DELETE 
    42 } MidgardAccessType; 
    43  
    44  
    45 extern MidgardID midgard_new_id (Midgard *midgard); 
    46  
    47 extern MidgardRecord *midgard_new (Midgard *midgard, 
    48                                    const MidgardTable *table); 
    49 extern gboolean midgard_init (Midgard *midgard, const MidgardTable *table, 
    50                               MidgardRecord *record); 
    51 extern gboolean midgard_done (Midgard *midgard, MidgardRecord *record); 
    52 extern gboolean midgard_free (Midgard *midgard, MidgardRecord *record); 
    53  
    54 extern GArray *midgard_list (Midgard *midgard, const MidgardTable *table, 
    55                              const gchar *name, const MidgardList *list); 
    56 extern MidgardRecord *midgard_get (Midgard *midgard, const MidgardTable *table, 
    57                                    MidgardID id); 
    58 extern gboolean midgard_fill (Midgard *midgard, MidgardRecord *record); 
    59 extern gboolean midgard_create (Midgard *midgard, MidgardRecord *record); 
    60 extern gboolean midgard_update (Midgard *midgard, MidgardRecord *record); 
    61 extern gboolean midgard_delete (Midgard *midgard, const MidgardTable *table, 
    62                                 MidgardID id); 
    63 extern gboolean midgard_access (Midgard *midgard, const MidgardTable *table, 
    64                                 MidgardID id, MidgardAccessType access_type); 
    65  
    66 struct MidgardList { 
    67         MidgardID id, up, link, owner; 
    68  
    69         MidgardID id1,   id2,   id3; 
    70         gint      int1,  int2,  int3; 
    71         time_t    time1, time2, time3; 
    72         gchar    *str1, *str2, *str3; 
    73 }; 
    74  
    75 struct MidgardRecord { 
    76         const MidgardTable *table; 
    77  
    78         MidgardID id, up, link, owner; 
    79         MidgardID creator, revisor, approver; 
    80         time_t    created, revised, approved; 
    81         guint     revision; 
    82 }; 
    83  
    84 extern const char *midgard_version(); 
     37extern const char *mgd_version(); 
    8538 
    8639/* Database connection */ 
    87 extern Midgard *midgard_handle_new (); 
    88 extern gboolean midgard_handle_free (Midgard *midgard); 
    89  
    90 extern gboolean midgard_connected (Midgard *midgard); 
    91 extern gboolean midgard_connect (Midgard *midgard, const char *database, 
    92                                  const char *username, const char *password); 
    93 extern gboolean midgard_close (Midgard *midgard); 
    94 extern gboolean midgard_auth (Midgard *midgard, 
    95                               const char *username, const char *password); 
    96 extern gboolean midgard_clear (Midgard *midgard); 
    97 extern const char *midgard_error (Midgard *midgard); 
     40extern midgard *mgd_connect(const char *database, 
     41                            const char *username, const char *password); 
     42extern void mgd_close(midgard *mgd); 
     43extern int mgd_auth(midgard *mgd, const char *username, const char *password); 
     44extern void mgd_clear(midgard *mgd); 
     45extern int mgd_errno(midgard *mgd); 
     46extern const char *mgd_error(midgard *mgd); 
    9847 
    9948/* User information */ 
    100 extern MidgardID midgard_user (Midgard *midgard); 
    101 extern gboolean midgard_isauser (Midgard *midgard); 
    102 extern gboolean midgard_isadmin (Midgard *midgard); 
    103 extern gboolean midgard_isuser (Midgard *midgard, MidgardID user); 
    104 extern gboolean midgard_ismember (Midgard *midgard, MidgardID group); 
    105 extern int *midgard_groups(Midgard *midgard); 
     49extern int mgd_user(midgard *mgd); 
     50extern int mgd_isauser(midgard *mgd); 
     51extern int mgd_isadmin(midgard *mgd); 
     52extern int mgd_isuser(midgard *mgd, int user); 
     53extern int mgd_ismember(midgard *mgd, int group); 
     54extern int *mgd_groups(midgard *mgd); 
    10655 
    107 /* Record types */ 
     56/* Data retrieval */ 
     57extern midgard_res *mgd_query(midgard *mgd, const char *query, ...); 
     58extern midgard_res *mgd_vquery(midgard *mgd, const char *query, va_list args); 
     59extern midgard_res *mgd_select(midgard *mgd, 
     60                               const char *fields, const char *from, 
     61                               const char *where, const char *sort, ...); 
     62extern midgard_res *mgd_vselect(midgard *mgd, 
     63                                const char *fields, const char *from, 
     64                                const char *where, const char *sort, 
     65                                va_list args); 
     66extern midgard_res *mgd_record(midgard *mgd, 
     67                               const char *fields, const char *table, int id); 
     68extern midgard_res *mgd_record_by_name(midgard *mgd, 
     69                        const char *fields, const char *table,  
     70                        const char* idfield, int id, const char* name); 
     71extern midgard_res *mgd_record_by_name2(midgard *mgd, 
     72                        const char *fields, const char *table,  
     73                        const char *firstfield, const char *first,  
     74                        const char *secondfield, const char *second); 
     75extern midgard_res *mgd_record_by_name_only(midgard *mgd, 
     76                        const char *fields, const char *table,  
     77                        const char* name); 
     78extern int mgd_idfield(midgard *mgd, 
     79                       const char *field, const char *table, int id); 
     80extern int mgd_exists(midgard *mgd, const char *from, const char *where, ...); 
    10881 
    109 #define MIDGARD_STYLE &midgard_style 
    110 #define MIDGARD_ELEMENT &midgard_element 
     82extern int mgd_fetch(midgard_res *res); 
     83extern void mgd_release(midgard_res *res); 
    11184 
    112 extern const MidgardTable midgard_style
    113 extern const MidgardTable midgard_element
     85extern int mgd_rows(midgard_res *res)
     86extern int mgd_cols(midgard_res *res)
    11487 
    115 typedef struct MidgardStyle { 
    116         MidgardRecord record; 
     88extern const char *mgd_colname(midgard_res *res, int col); 
     89extern const char *mgd_colvalue(midgard_res *res, int col); 
     90extern const char *mgd_column(midgard_res *res, const char *name); 
    11791 
    118         gchar *name; 
    119 } MidgardStyle; 
     92extern int mgd_sql2id(midgard_res *res, int col); 
     93extern int mgd_sql2int(midgard_res *res, int col); 
     94extern const char *mgd_sql2str(midgard_res *res, int col); 
     95extern time_t mgd_sql2date(midgard_res *res, int col); 
     96extern time_t mgd_sql2time(midgard_res *res, int col); 
     97extern time_t mgd_sql2datetime(midgard_res *res, int col); 
    12098 
    121 typedef struct MidgardElement { 
    122         MidgardRecord record; 
     99/* Data modification */ 
     100extern int mgd_exec(midgard *mgd, const char *command, ...); 
     101extern int mgd_vexec(midgard *mgd, const char *command, va_list args); 
     102extern int mgd_create(midgard *mgd, const char *table, 
     103                      const char *fields, const char *values, ...); 
     104extern int mgd_vcreate(midgard *mgd, const char *table, 
     105                       const char *fields, const char *values, va_list args); 
     106extern int mgd_update(midgard *mgd, const char *table, int id, 
     107                      const char *fields, ...); 
     </