]> git.sur5r.net Git - openldap/blob - servers/slapd/back-sql/util.c
e7458b7296ad244e648cd4ae92cb053863e6d21b
[openldap] / servers / slapd / back-sql / util.c
1 /*
2  *       Copyright 1999, Dmitry Kovalev <mit@openldap.org>, All rights reserved.
3  *
4  *       Redistribution and use in source and binary forms are permitted only
5  *       as authorized by the OpenLDAP Public License.  A copy of this
6  *       license is available at http://www.OpenLDAP.org/license.html or
7  *       in file LICENSE in the top-level directory of the distribution.
8  */
9
10 #include "portable.h"
11
12 #ifdef SLAPD_SQL
13
14 #include <stdio.h>
15 #include <sys/types.h>
16 #include "ac/string.h"
17 #include "ac/ctype.h"
18 #include "ac/stdarg.h"
19 #include "slap.h"
20 #include "back-sql.h"
21 #include "schema-map.h"
22 #include "util.h"
23
24
25 char backsql_def_oc_query[] = 
26         "SELECT id,name,keytbl,keycol,create_proc,delete_proc,expect_return "
27         "FROM ldap_oc_mappings";
28 char backsql_def_at_query[] = 
29         "SELECT name,sel_expr,from_tbls,join_where,add_proc,delete_proc,"
30         "param_order,expect_return,sel_expr_u FROM ldap_attr_mappings "
31         "WHERE oc_map_id=?";
32 char backsql_def_delentry_query[] = "DELETE FROM ldap_entries WHERE id=?";
33 char backsql_def_insentry_query[] = 
34         "INSERT INTO ldap_entries (dn,oc_map_id,parent,keyval) "
35         "VALUES (?,?,?,?)";
36 char backsql_def_subtree_cond[] = "ldap_entries.dn LIKE CONCAT('%',?)";
37 char backsql_def_upper_subtree_cond[] = "(ldap_entries.dn) LIKE CONCAT('%',?)";
38 char backsql_id_query[] = "SELECT id,keyval,oc_map_id FROM ldap_entries WHERE ";
39
40 /* TimesTen */
41 char backsql_check_dn_ru_query[] = "SELECT dn_ru from ldap_entries";
42
43 struct berval *
44 backsql_strcat( struct berval *dest, int *buflen, ... )
45 {
46         va_list         strs;
47         int             cdlen, cslen, grow;
48         char            *cstr;
49
50         assert( dest );
51         assert( dest->bv_val == NULL 
52                         || dest->bv_len == strlen( dest->bv_val ) );
53  
54 #if 0
55         Debug( LDAP_DEBUG_TRACE, "==>backsql_strcat()\n" );
56 #endif
57
58         va_start( strs, buflen );
59         if ( dest->bv_val == NULL || *buflen <= 0 ) {
60                 dest->bv_val = (char *)ch_calloc( BACKSQL_STR_GROW, 
61                                 sizeof( char ) );
62                 dest->bv_len = 0;
63                 *buflen = BACKSQL_STR_GROW;
64         }
65         cdlen = dest->bv_len;
66         while ( ( cstr = va_arg( strs, char * ) ) != NULL ) {
67                 cslen = strlen( cstr );
68                 grow = BACKSQL_MAX( BACKSQL_STR_GROW, cslen );
69                 if ( *buflen - cdlen <= cslen ) {
70                         char    *tmp_dest;
71
72 #if 0
73                         Debug( LDAP_DEBUG_TRACE, "backsql_strcat(): "
74                                 "buflen=%d, cdlen=%d, cslen=%d "
75                                 "-- reallocating dest\n",
76                                 *buflen, cdlen + 1, cslen );
77 #endif
78                         tmp_dest = (char *)ch_realloc( dest->bv_val,
79                                         ( *buflen ) + grow * sizeof( char ) );
80                         if ( tmp_dest == NULL ) {
81                                 Debug( LDAP_DEBUG_ANY, "backsql_strcat(): "
82                                         "could not reallocate string buffer.\n",
83                                         0, 0, 0 );
84                                 return NULL;
85                         }
86                         dest->bv_val = tmp_dest;
87                         *buflen += grow;
88 #if 0
89                         Debug( LDAP_DEBUG_TRACE, "backsql_strcat(): "
90                                 "new buflen=%d, dest=%p\n", *buflen, dest, 0 );
91 #endif
92                 }
93                 AC_MEMCPY( dest->bv_val + cdlen, cstr, cslen + 1 );
94                 cdlen += cslen;
95         }
96         va_end( strs );
97
98 #if 0
99         Debug( LDAP_DEBUG_TRACE, "<==backsql_strcat() (dest='%s')\n", 
100                         dest, 0, 0 );
101 #endif
102
103         dest->bv_len = cdlen;
104
105         return dest;
106
107
108 int
109 backsql_entry_addattr(
110         Entry           *e,
111         char            *at_name,
112         char            *at_val, 
113         unsigned int    at_val_len )
114 {
115         struct berval           add_val[ 2 ];
116         AttributeDescription    *ad;
117         int                     rc;
118         const char              *text;
119
120         Debug( LDAP_DEBUG_TRACE, "backsql_entry_addattr(): "
121                 "at_name='%s', at_val='%s'\n", at_name, at_val, 0 );
122         add_val[ 0 ].bv_val = at_val;
123         add_val[ 0 ].bv_len = at_val_len;
124         add_val[ 1 ].bv_val = NULL;
125         add_val[ 1 ].bv_len = 0;
126
127         ad = NULL;
128         rc = slap_str2ad( at_name, &ad, &text );
129         if ( rc != LDAP_SUCCESS ) {
130                 Debug( LDAP_DEBUG_TRACE, "backsql_entry_addattr(): "
131                         "failed to find AttributeDescription for '%s'\n",
132                         at_name, 0, 0 );
133                 return 0;
134         }
135
136         rc = attr_merge( e, ad, add_val );
137
138         if ( rc != 0 ) {
139                 Debug( LDAP_DEBUG_TRACE, "backsql_entry_addattr(): "
140                         "failed to merge value '%s' for attribute '%s'\n",
141                         at_val, at_name, 0 );
142                 return 0;
143         }
144         
145         Debug( LDAP_DEBUG_TRACE, "<==backsql_query_addattr()\n", 0, 0, 0 );
146         return 1;
147 }
148
149 char *
150 backsql_get_table_spec( char **p )
151 {
152         char            *s, *q;
153         struct berval   res = { 0, NULL };
154         int             res_len = 0;
155
156         s = *p;
157         while ( **p && **p != ',' ) {
158                 (*p)++;
159         }
160
161         if ( **p ) {
162                 *(*p)++ = '\0';
163         }
164         
165 #define BACKSQL_NEXT_WORD { \
166                 while ( *s && isspace( (unsigned char)*s ) ) s++; \
167                 if ( !*s ) return res.bv_val; \
168                 q = s; \
169                 while ( *q && !isspace( (unsigned char)*q ) ) q++; \
170                 if ( *q ) *q++='\0'; \
171         }
172
173         BACKSQL_NEXT_WORD;
174         /* table name */
175         backsql_strcat( &res, &res_len, s, NULL );
176         s = q;
177
178         BACKSQL_NEXT_WORD;
179         if ( !strcasecmp( s, "as" ) ) {
180                 s = q;
181                 BACKSQL_NEXT_WORD;
182         }
183 #if 0
184         backsql_strcat( &res, &res_len, " AS ", s, NULL );
185         /* oracle doesn't understand AS :( */
186 #endif
187         /* table alias */
188         backsql_strcat( &res, &res_len, " ", s, NULL);
189         return res.bv_val;
190 }
191
192 int
193 backsql_merge_from_clause( char **dest_from, int *dest_len, char *src_from )
194 {
195         char            *s, *p, *srcc, *pos, e;
196         struct berval   res = { 0 , NULL };
197
198 #if 0
199         Debug( LDAP_DEBUG_TRACE, "==>backsql_merge_from_clause(): "
200                 "dest_from='%s',src_from='%s'\n",
201                 dest_from, src_from, 0 );
202 #endif
203         srcc = ch_strdup( src_from );
204         p = srcc;
205
206         if ( *dest_from != NULL ) {
207                 res.bv_val = *dest_from;
208                 res.bv_len = strlen( *dest_from );
209         }
210         
211         while ( *p ) {
212                 s = backsql_get_table_spec( &p );
213 #if 0
214                 Debug( LDAP_DEBUG_TRACE, "backsql_merge_from_clause(): "
215                         "p='%s' s='%s'\n", p, s, 0 );
216 #endif
217                 if ( res.bv_val == NULL ) {
218                         backsql_strcat( &res, dest_len, s, NULL );
219
220                 } else {
221                         pos = strstr( res.bv_val, s );
222                         if ( pos == NULL ) {
223                                 backsql_strcat( &res, dest_len, ",", s, NULL );
224                         } else if ( ( e = pos[ strlen( s ) ] ) != '\0' && e != ',' ) {
225                                 backsql_strcat( &res, dest_len, ",", s, NULL );
226                         }
227                 }
228                 
229                 if ( s ) {
230                         ch_free( s );
231                 }
232         }
233 #if 0
234         Debug( LDAP_DEBUG_TRACE, "<==backsql_merge_from_clause()\n", 0, 0, 0 );
235 #endif
236         free( srcc );
237         *dest_from = res.bv_val;
238
239         return 1;
240 }
241
242 #endif /* SLAPD_SQL */
243