]> granicus.if.org Git - postgresql/blob - src/interfaces/odbc/columninfo.c
Version 06-30-0248
[postgresql] / src / interfaces / odbc / columninfo.c
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 "columninfo.h"
16 #include "socket.h"
17 #include <stdlib.h>
18 #include <malloc.h>
19 #include <string.h>
20
21 ColumnInfoClass *
22 CI_Constructor()
23 {
24 ColumnInfoClass *rv;
25
26         rv = (ColumnInfoClass *) malloc(sizeof(ColumnInfoClass));
27
28         if (rv) {
29                 rv->num_fields = 0;
30                 rv->name = NULL;
31                 rv->adtid = NULL;
32                 rv->adtsize = NULL;
33                 rv->display_size = NULL;
34         }
35
36         return rv;
37 }
38
39 void
40 CI_Destructor(ColumnInfoClass *self)
41 {
42         CI_free_memory(self);
43
44         free(self);
45 }
46
47 /*  Read in field descriptions.
48     If self is not null, then also store the information.
49         If self is null, then just read, don't store.
50 */
51 char
52 CI_read_fields(ColumnInfoClass *self, SocketClass *sock)
53 {
54 Int2 lf;
55 int new_num_fields;
56 Oid new_adtid;
57 Int2 new_adtsize;
58 char new_field_name[MAX_MESSAGE_LEN+1];
59
60
61         /* at first read in the number of fields that are in the query */
62         new_num_fields = (Int2) SOCK_get_int(sock, sizeof(Int2));
63
64         mylog("num_fields = %d\n", new_num_fields);
65
66         if (self) {     /* according to that allocate memory */
67                 CI_set_num_fields(self, new_num_fields);
68         }
69
70         /* now read in the descriptions */
71         for(lf = 0; lf < new_num_fields; lf++) {
72
73                 SOCK_get_string(sock, new_field_name, MAX_MESSAGE_LEN);
74                 new_adtid = (Oid) SOCK_get_int(sock, 4);
75                 new_adtsize = (Int2) SOCK_get_int(sock, 2);
76
77                 mylog("CI_read_fields: fieldname='%s', adtid=%d, adtsize=%d\n", new_field_name, new_adtid, new_adtsize);
78
79                 if (self)
80                         CI_set_field_info(self, lf, new_field_name, new_adtid, new_adtsize);
81         }
82
83         return (SOCK_get_errcode(sock) == 0);
84 }
85
86
87
88 void
89 CI_free_memory(ColumnInfoClass *self)
90 {
91 register Int2 lf;
92 int num_fields = self->num_fields;
93
94         for (lf = 0; lf < num_fields; lf++) {
95                 if( self->name[lf])
96                         free (self->name[lf]);
97         }
98
99         /*      Safe to call even if null */
100         free(self->name);
101         free(self->adtid);
102         free(self->adtsize);
103         free(self->display_size);
104 }
105
106 void
107 CI_set_num_fields(ColumnInfoClass *self, int new_num_fields)
108 {
109         CI_free_memory(self);   /* always safe to call */
110
111         self->num_fields = new_num_fields;
112
113         self->name = (char **) malloc (sizeof(char *) * self->num_fields);
114         self->adtid = (Oid *) malloc (sizeof(Oid) * self->num_fields);
115         self->adtsize = (Int2 *) malloc (sizeof(Int2) * self->num_fields);
116         self->display_size = (Int2 *) malloc(sizeof(Int2) * self->num_fields);
117 }
118
119 void
120 CI_set_field_info(ColumnInfoClass *self, int field_num, char *new_name, 
121                                       Oid new_adtid, Int2 new_adtsize)
122 {
123     
124         // check bounds
125         if((field_num < 0) || (field_num >= self->num_fields)) {
126                 return;
127         }
128
129         // store the info
130         self->name[field_num] = strdup(new_name);  
131         self->adtid[field_num] = new_adtid;
132         self->adtsize[field_num] = new_adtsize;
133
134         self->display_size[field_num] = 0;
135 }
136