pg_oid.c

Go to the documentation of this file.
00001 /* 
00002  * $Id$ 
00003  *
00004  * PostgreSQL Database Driver for SER
00005  *
00006  * Portions Copyright (C) 2001-2003 FhG FOKUS
00007  * Copyright (C) 2003 August.Net Services, LLC
00008  * Portions Copyright (C) 2005-2008 iptelorg GmbH
00009  *
00010  * This file is part of SER, a free SIP server.
00011  *
00012  * SER is free software; you can redistribute it and/or modify it under the
00013  * terms of the GNU General Public License as published by the Free Software
00014  * Foundation; either version 2 of the License, or (at your option) any later
00015  * version
00016  *
00017  * For a license to use the ser software under conditions other than those
00018  * described here, or to purchase support for this software, please contact
00019  * iptel.org by e-mail at the following addresses: info@iptel.org
00020  *
00021  * SER is distributed in the hope that it will be useful, but WITHOUT ANY
00022  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00023  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
00024  * details.
00025  *
00026  * You should have received a copy of the GNU General Public License along
00027  * with this program; if not, write to the Free Software Foundation, Inc., 59
00028  * Temple Place, Suite 330, Boston, MA 02111-1307 USA
00029  */
00030 
00040 #include "pg_oid.h"
00041 #include "../../dprint.h"
00042 #include "../../ut.h"
00043 #include <strings.h>
00044 #include <stdlib.h>
00045 #include <string.h>
00046 
00048 static char* pg_type_id_name[] = {
00049         "bool",
00050         "bytea",
00051         "char",
00052         "int8",
00053         "int2",
00054         "int4",
00055         "text",
00056         "float4",
00057         "float8",
00058         "inet",
00059         "bpchar",
00060         "varchar",
00061         "timestamp",
00062         "timestamptz",
00063         "bit",
00064         "varbit",
00065 };
00066 
00067 
00068 static int get_index(char* name)
00069 {
00070         int i;
00071         
00072         for(i = 0; i < PG_ID_MAX; i++) {
00073                 if (strcasecmp(name, pg_type_id_name[i]) == 0) return i; 
00074         }
00075         return -1;
00076 }
00077 
00078 
00079 pg_type_t* pg_new_oid_table(PGresult* res)
00080  {
00081         pg_type_t* table = NULL;
00082         int row, n = 0, end, idx, fields;
00083         str s;
00084         
00085         if (res == NULL || PQresultStatus(res) != PGRES_TUPLES_OK) goto error;
00086 
00087         n = PQntuples(res);
00088         if (n <= 0) goto error;
00089         fields = PQnfields(res);
00090         if (fields != 2) goto error;
00091 
00092         table = (pg_type_t*)malloc(sizeof(pg_type_t) * (n + 1));
00093         if (table == NULL) goto error;
00094         memset(table, '\0', sizeof(pg_type_t) * (n + 1));
00095         
00096         end = n - 1;
00097         for(row = 0; row < n; row++) {
00098 
00099                 /* Get name */
00100                 s.s = PQgetvalue(res, row, 0);
00101                 if (s.s == NULL) goto error;
00102 
00103                 /* Find index where the record is to be stored */
00104                 idx = get_index(s.s);
00105                 if (idx == -1) idx = end--;
00106 
00107                 /* Store the name */
00108                 table[idx].name = strdup(s.s);
00109                 if (table[idx].name == NULL) goto error;
00110 
00111                 /* Oid */
00112                 s.s = PQgetvalue(res, row, 1);
00113                 if (s.s == NULL) goto error;
00114                 s.len = strlen(s.s);
00115                 if (str2int(&s, &table[idx].oid) < 0) goto error;
00116 
00117                 DBG("postgres: Type %s maps to Oid %d\n", table[idx].name, table[idx].oid);
00118         }
00119         return table;
00120         
00121  error:
00122         ERR("postgres: Error while obtaining field/data type description from server\n");
00123         if (table) {
00124                 for(idx = 0; idx < n; idx++) {
00125                         if (table[idx].name) free(table[idx].name);
00126                 }
00127                 free(table);
00128         }
00129         return NULL;
00130 }
00131 
00132 
00133 void pg_destroy_oid_table(pg_type_t* table)
00134 {
00135         int i;
00136         if (table) {
00137                 for(i = 0; table[i].name; i++) {
00138                         free(table[i].name);
00139                 }
00140                 free(table);
00141         }
00142 }
00143 
00144 
00145 int pg_name2oid(Oid* oid, pg_type_t* table, const char* name)
00146 {
00147         int i;
00148 
00149         if (!oid || !table) {
00150                 BUG("postgres: Invalid parameters to pg_name2oid\n");
00151                 return -1;
00152         }
00153 
00154         if (name == NULL || name[0] == '\0') return 1;
00155 
00156         for(i = 0; table[i].name; i++) {
00157                 if (strcasecmp(table[i].name, name) == 0) {
00158                         *oid = table[i].oid;
00159                         return 0;
00160                 }
00161         }
00162         return 1;
00163 }
00164 
00165 
00166 int pg_oid2name(const char** name, pg_type_t* table, Oid oid)
00167 {
00168         int i;
00169 
00170         if (!table || !name) {
00171                 BUG("postgres: Invalid parameters to pg_oid2name\n");
00172                 return -1;
00173         }
00174 
00175         for(i = 0; table[i].name; i++) {
00176                 if (oid == table[i].oid) {
00177                         *name = table[i].name;
00178                         return 0;
00179                 }
00180         }
00181         return 1;
00182 }
00183