~ubuntu-branches/ubuntu/gutsy/psqlodbc/gutsy

« back to all changes in this revision

Viewing changes to columninfo.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2004-05-13 10:47:36 UTC
  • Revision ID: james.westby@ubuntu.com-20040513104736-a530gmn0p3knep89
Tags: upstream-07.03.0200
ImportĀ upstreamĀ versionĀ 07.03.0200

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*-------
 
2
 * Module:                      columninfo.c
 
3
 *
 
4
 * Description:         This module contains routines related to
 
5
 *                                      reading and storing the field information from a query.
 
6
 *
 
7
 * Classes:                     ColumnInfoClass (Functions prefix: "CI_")
 
8
 *
 
9
 * API functions:       none
 
10
 *
 
11
 * Comments:            See "notice.txt" for copyright and license information.
 
12
 *-------
 
13
 */
 
14
 
 
15
#include "pgtypes.h"
 
16
#include "columninfo.h"
 
17
 
 
18
#include "connection.h"
 
19
#include "socket.h"
 
20
#include <stdlib.h>
 
21
#include <string.h>
 
22
#include "pgapifunc.h"
 
23
 
 
24
ColumnInfoClass *
 
25
CI_Constructor()
 
26
{
 
27
        ColumnInfoClass *rv;
 
28
 
 
29
        rv = (ColumnInfoClass *) malloc(sizeof(ColumnInfoClass));
 
30
 
 
31
        if (rv)
 
32
        {
 
33
                rv->num_fields = 0;
 
34
                rv->name = NULL;
 
35
                rv->adtid = NULL;
 
36
                rv->adtsize = NULL;
 
37
                rv->display_size = NULL;
 
38
                rv->atttypmod = NULL;
 
39
        }
 
40
 
 
41
        return rv;
 
42
}
 
43
 
 
44
 
 
45
void
 
46
CI_Destructor(ColumnInfoClass *self)
 
47
{
 
48
        CI_free_memory(self);
 
49
 
 
50
        free(self);
 
51
}
 
52
 
 
53
 
 
54
/*
 
55
 *      Read in field descriptions.
 
56
 *      If self is not null, then also store the information.
 
57
 *      If self is null, then just read, don't store.
 
58
 */
 
59
char
 
60
CI_read_fields(ColumnInfoClass *self, ConnectionClass *conn)
 
61
{
 
62
        Int2            lf;
 
63
        int                     new_num_fields;
 
64
        Oid                     new_adtid;
 
65
        Int2            new_adtsize;
 
66
        Int4            new_atttypmod = -1;
 
67
 
 
68
        /* COLUMN_NAME_STORAGE_LEN may be sufficient but for safety */
 
69
        char            new_field_name[2 * COLUMN_NAME_STORAGE_LEN + 1];
 
70
        SocketClass *sock;
 
71
        ConnInfo   *ci;
 
72
 
 
73
        sock = CC_get_socket(conn);
 
74
        ci = &conn->connInfo;
 
75
 
 
76
        /* at first read in the number of fields that are in the query */
 
77
        new_num_fields = (Int2) SOCK_get_int(sock, sizeof(Int2));
 
78
 
 
79
        mylog("num_fields = %d\n", new_num_fields);
 
80
 
 
81
        if (self)
 
82
                /* according to that allocate memory */
 
83
                CI_set_num_fields(self, new_num_fields);
 
84
 
 
85
        /* now read in the descriptions */
 
86
        for (lf = 0; lf < new_num_fields; lf++)
 
87
        {
 
88
                SOCK_get_string(sock, new_field_name, 2 * COLUMN_NAME_STORAGE_LEN);
 
89
                new_adtid = (Oid) SOCK_get_int(sock, 4);
 
90
                new_adtsize = (Int2) SOCK_get_int(sock, 2);
 
91
 
 
92
                /* If 6.4 protocol, then read the atttypmod field */
 
93
                if (PG_VERSION_GE(conn, 6.4))
 
94
                {
 
95
                        mylog("READING ATTTYPMOD\n");
 
96
                        new_atttypmod = (Int4) SOCK_get_int(sock, 4);
 
97
 
 
98
                        /* Subtract the header length */
 
99
                        switch (new_adtid)
 
100
                        {
 
101
                                case PG_TYPE_DATETIME:
 
102
                                case PG_TYPE_TIMESTAMP_NO_TMZONE:
 
103
                                case PG_TYPE_TIME:
 
104
                                case PG_TYPE_TIME_WITH_TMZONE:
 
105
                                        break;
 
106
                                default:
 
107
                                        new_atttypmod -= 4;
 
108
                        }
 
109
                        if (new_atttypmod < 0)
 
110
                                new_atttypmod = -1;
 
111
 
 
112
                }
 
113
 
 
114
                mylog("CI_read_fields: fieldname='%s', adtid=%d, adtsize=%d, atttypmod=%d\n", new_field_name, new_adtid, new_adtsize, new_atttypmod);
 
115
 
 
116
                if (self)
 
117
                        CI_set_field_info(self, lf, new_field_name, new_adtid, new_adtsize, new_atttypmod);
 
118
        }
 
119
 
 
120
        return (SOCK_get_errcode(sock) == 0);
 
121
}
 
122
 
 
123
 
 
124
void
 
125
CI_free_memory(ColumnInfoClass *self)
 
126
{
 
127
        register Int2 lf;
 
128
        int                     num_fields = self->num_fields;
 
129
 
 
130
        for (lf = 0; lf < num_fields; lf++)
 
131
        {
 
132
                if (self->name[lf])
 
133
                {
 
134
                        free(self->name[lf]);
 
135
                        self->name[lf] = NULL;
 
136
                }
 
137
        }
 
138
 
 
139
        /* Safe to call even if null */
 
140
        self->num_fields = 0;
 
141
        if (self->name)
 
142
                free(self->name);
 
143
        self->name = NULL;
 
144
        if (self->adtid)
 
145
                free(self->adtid);
 
146
        self->adtid = NULL;
 
147
        if (self->adtsize)
 
148
                free(self->adtsize);
 
149
        self->adtsize = NULL;
 
150
        if (self->display_size)
 
151
                free(self->display_size);
 
152
        self->display_size = NULL;
 
153
 
 
154
        if (self->atttypmod)
 
155
                free(self->atttypmod);
 
156
        self->atttypmod = NULL;
 
157
}
 
158
 
 
159
 
 
160
void
 
161
CI_set_num_fields(ColumnInfoClass *self, int new_num_fields)
 
162
{
 
163
        CI_free_memory(self);           /* always safe to call */
 
164
 
 
165
        self->num_fields = new_num_fields;
 
166
 
 
167
        self->name = (char **) malloc(sizeof(char *) * self->num_fields);
 
168
        memset(self->name, 0, sizeof(char *) * self->num_fields);
 
169
        self->adtid = (Oid *) malloc(sizeof(Oid) * self->num_fields);
 
170
        self->adtsize = (Int2 *) malloc(sizeof(Int2) * self->num_fields);
 
171
        self->display_size = (Int2 *) malloc(sizeof(Int2) * self->num_fields);
 
172
        self->atttypmod = (Int4 *) malloc(sizeof(Int4) * self->num_fields);
 
173
}
 
174
 
 
175
 
 
176
void
 
177
CI_set_field_info(ColumnInfoClass *self, int field_num, char *new_name,
 
178
                                  Oid new_adtid, Int2 new_adtsize, Int4 new_atttypmod)
 
179
{
 
180
        /* check bounds */
 
181
        if ((field_num < 0) || (field_num >= self->num_fields))
 
182
                return;
 
183
 
 
184
        /* store the info */
 
185
        self->name[field_num] = strdup(new_name);
 
186
        self->adtid[field_num] = new_adtid;
 
187
        self->adtsize[field_num] = new_adtsize;
 
188
        self->atttypmod[field_num] = new_atttypmod;
 
189
 
 
190
        self->display_size[field_num] = 0;
 
191
}