1 /* -*-pgsql-c-*- */
2 /*
3  * $Header$
4  *
5  * pgpool: a language independent connection pool server for PostgreSQL
6  * written by Tatsuo Ishii
7  *
8  * Copyright (c) 2003-2008	PgPool Global Development Group
9  *
10  * Permission to use, copy, modify, and distribute this software and
11  * its documentation for any purpose and without fee is hereby
12  * granted, provided that the above copyright notice appear in all
13  * copies and that both that copyright notice and this permission
14  * notice appear in supporting documentation, and that the name of the
15  * author not be used in advertising or publicity pertaining to
16  * distribution of the software without specific, written prior
17  * permission. The author makes no representations about the
18  * suitability of this software for any purpose.  It is provided "as
19  * is" without express or implied warranty.
20  *
21  * params.c: Parameter Status handling routines
22  *
23  */
24 #include "config.h"
25 
26 #include <stdlib.h>
27 #include <string.h>
28 #include "utils/elog.h"
29 
30 #include "pool.h"
31 #include "parser/parser.h"
32 #include "utils/palloc.h"
33 #include "utils/memutils.h"
34 
35 #define MAX_PARAM_ITEMS 128
36 
37 /*
38  * initialize parameter structure
39  */
pool_init_params(ParamStatus * params)40 int pool_init_params(ParamStatus *params)
41 {
42     MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext);
43 
44     params->num = 0;
45     params->names = palloc(MAX_PARAM_ITEMS*sizeof(char *));
46     params->values = palloc(MAX_PARAM_ITEMS*sizeof(char *));
47 
48     MemoryContextSwitchTo(oldContext);
49 
50 	return 0;
51 }
52 
53 /*
54  * discard parameter structure
55  */
pool_discard_params(ParamStatus * params)56 void pool_discard_params(ParamStatus *params)
57 {
58     int i;
59 
60     for (i=0;i<params->num;i++)
61     {
62 		pfree(params->names[i]);
63 		pfree(params->values[i]);
64     }
65     if(params->names)
66         pfree(params->names);
67     if(params->values)
68         pfree(params->values);
69     params->num = 0;
70     params->names = NULL;
71     params->values = NULL;
72 
73 }
74 
75 /*
76  * find param value by name. if found, its value is returned
77  * also, pos is set
78  * if not found, NULL is returned
79  */
pool_find_name(ParamStatus * params,char * name,int * pos)80 char *pool_find_name(ParamStatus *params, char *name, int *pos)
81 {
82     int i;
83 
84     for (i=0;i<params->num;i++)
85     {
86 		if (!strcmp(name, params->names[i]))
87 		{
88 			*pos = i;
89 			return params->values[i];
90 		}
91     }
92     return NULL;
93 }
94 
95 /*
96  * return name and value by index.
97  */
pool_get_param(ParamStatus * params,int index,char ** name,char ** value)98 int pool_get_param(ParamStatus *params, int index, char **name, char **value)
99 {
100 	if (index < 0 || index >= params->num)
101 		return -1;
102 
103 	*name = params->names[index];
104 	*value = params->values[index];
105 
106 	return 0;
107 }
108 
109 /*
110  * add or replace name/value pair
111  */
pool_add_param(ParamStatus * params,char * name,char * value)112 int pool_add_param(ParamStatus *params, char *name, char *value)
113 {
114     int pos;
115     MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext);
116 
117     if (pool_find_name(params, name, &pos))
118     {
119 		/* name already exists */
120 		if (strlen(params->values[pos]) < strlen(value))
121 		{
122 			params->values[pos] = repalloc(params->values[pos], strlen(value) + 1);
123 		}
124 		strcpy(params->values[pos], value);
125     }
126     else
127     {
128 		int num;
129 
130 		/* add name/value pair */
131 		if (params->num >= MAX_PARAM_ITEMS)
132 		{
133             ereport(ERROR,
134 				(errmsg("add parameter failed"),
135                      errdetail("no more room for num")));
136 		}
137 		num = params->num;
138 		params->names[num] = pstrdup(name);
139 		params->values[num] = pstrdup(value);
140 		params->num++;
141     }
142 	parser_set_param(name, value);
143     MemoryContextSwitchTo(oldContext);
144 
145 	return 0;
146 }
147 
pool_param_debug_print(ParamStatus * params)148 void pool_param_debug_print(ParamStatus *params)
149 {
150 	int i;
151 
152     for (i=0;i<params->num;i++)
153     {
154 		ereport(DEBUG2,
155 			(errmsg("No.%d: name: %s value: %s", i, params->names[i], params->values[i])));
156 	}
157 }
158