]> git.sur5r.net Git - openldap/blob - servers/slapd/back-sql/schema-map.c
Fix previous idl_find patch. Cannot test <=0 with unsigned ints, duh...
[openldap] / servers / slapd / back-sql / schema-map.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 <string.h>
17 #include "slap.h"
18 #include "back-sql.h"
19 #include "sql-wrap.h"
20 #include "schema-map.h"
21 #include "util.h"
22
23 int backsql_dummy(void *,void *);
24
25 int backsql_cmp_oc_name(backsql_oc_map_rec *m1,backsql_oc_map_rec *m2)
26 {
27  return strcasecmp(m1->name,m2->name);
28 }
29
30 int backsql_cmp_oc_id(backsql_oc_map_rec *m1,backsql_oc_map_rec *m2)
31 {
32  if (m1->id < m2->id)
33   return -1;
34  if (m1->id > m2->id)
35   return 1;
36  return 0;
37 }
38
39 int backsql_cmp_attr(backsql_at_map_rec *m1,backsql_at_map_rec *m2)
40 {
41  return strcasecmp(m1->name,m2->name);
42 }
43
44 char* backsql_make_attr_query(backsql_oc_map_rec *oc_map,backsql_at_map_rec *at_map)
45 {
46  char *tmps;
47  int tmpslen;
48
49  tmps=NULL;tmpslen=0;
50  tmps=backsql_strcat(tmps,&tmpslen,"SELECT ",at_map->sel_expr," AS ",at_map->name,
51                         " FROM ",at_map->from_tbls,
52                         " WHERE ",oc_map->keytbl,".",oc_map->keycol,"=?",NULL);
53  if (at_map->join_where!=NULL && at_map->join_where[0]!='\0')
54   tmps=backsql_strcat(tmps,&tmpslen," AND ",at_map->join_where,NULL);
55  at_map->query=ch_strdup(tmps);
56  ch_free(tmps);
57  return at_map->query;
58 }
59
60
61 int backsql_add_sysmaps(backsql_oc_map_rec *oc_map)
62 {
63  backsql_at_map_rec *at_map;
64  int len;
65  char s[30]; 
66
67  sprintf(s,"%d",oc_map->id);
68  at_map=(backsql_at_map_rec*)ch_calloc(1,sizeof(backsql_at_map_rec));
69  at_map->name=ch_strdup("objectClass");
70  at_map->sel_expr=ch_strdup("ldap_entry_objclasses.oc_name");
71  at_map->from_tbls=ch_strdup("ldap_entry_objclasses,ldap_entries");
72  len=strlen(at_map->from_tbls);
73  backsql_merge_from_clause(&at_map->from_tbls,&len,oc_map->keytbl);
74  at_map->join_where=NULL; len=0;
75  at_map->join_where=backsql_strcat(at_map->join_where,&len,
76                         "ldap_entries.id=ldap_entry_objclasses.entry_id and ldap_entries.keyval=",
77                         oc_map->keytbl,".",oc_map->keycol," and ldap_entries.oc_map_id=",s,NULL);
78  at_map->add_proc=NULL;
79  at_map->delete_proc=NULL;
80  at_map->param_order=0;
81  at_map->expect_return=0;
82  backsql_make_attr_query(oc_map,at_map);
83  avl_insert(&oc_map->attrs,at_map,(AVL_CMP)backsql_cmp_attr,backsql_dummy);
84
85  at_map=(backsql_at_map_rec*)ch_calloc(1,sizeof(backsql_at_map_rec));
86  at_map->name=ch_strdup("ref");
87  at_map->sel_expr=ch_strdup("ldap_referrals.url");
88  at_map->from_tbls=ch_strdup("ldap_referrals,ldap_entries");
89  len=strlen(at_map->from_tbls);
90  backsql_merge_from_clause(&at_map->from_tbls,&len,oc_map->keytbl);
91  at_map->join_where=NULL; len=0;
92  at_map->join_where=backsql_strcat(at_map->join_where,&len,
93                         "ldap_entries.id=ldap_referrals.entry_id and ldap_entries.keyval=",
94                         oc_map->keytbl,".",oc_map->keycol," and ldap_entries.oc_map_id=",s,NULL);
95  at_map->add_proc=NULL;
96  at_map->delete_proc=NULL;
97  at_map->param_order=0;
98  at_map->expect_return=0;
99  backsql_make_attr_query(oc_map,at_map);
100  avl_insert(&oc_map->attrs,at_map,(AVL_CMP)backsql_cmp_attr,backsql_dummy);
101
102  return 1;
103 }
104
105 int backsql_load_schema_map(backsql_info *si,SQLHDBC dbh)
106 {
107  SQLHSTMT oc_sth,at_sth;
108  RETCODE rc;
109  BACKSQL_ROW_NTS oc_row,at_row;
110  unsigned long oc_id;
111  backsql_oc_map_rec *oc_map;
112  backsql_at_map_rec *at_map;
113  char *tmps;
114  int tmpslen;
115
116  Debug(LDAP_DEBUG_TRACE,"==>load_schema_map()\n",0,0,0);
117
118  /* TimesTen : See if the ldap_entries.dn_ru field exists in the schema. */
119
120  rc = backsql_Prepare(dbh, &oc_sth, backsql_check_dn_ru_query, 0);
121  if (rc == SQL_SUCCESS) {
122    si->has_ldapinfo_dn_ru = 1;  /* Yes, the field exists */
123    Debug(LDAP_DEBUG_TRACE, "ldapinfo.dn_ru field exists in the schema\n", 0, 0,0);
124  }
125  else {
126    si->has_ldapinfo_dn_ru = 0;  /* No such field exists */
127  }
128
129  SQLFreeStmt(oc_sth, SQL_DROP);
130
131  rc=backsql_Prepare(dbh,&oc_sth,si->oc_query,0);
132  if (rc != SQL_SUCCESS)
133   {
134    Debug(LDAP_DEBUG_TRACE,"load_schema_map(): error preparing oc_query: '%s'\n",si->oc_query,0,0);
135    backsql_PrintErrors(si->db_env,dbh,oc_sth,rc);
136    return -1;
137   }
138   Debug(LDAP_DEBUG_TRACE, "load_schema_map(): at_query '%s'\n", si->at_query,0,0);
139
140  rc=backsql_Prepare(dbh,&at_sth,si->at_query,0);
141  if (rc != SQL_SUCCESS)
142   {
143    Debug(LDAP_DEBUG_TRACE,"load_schema_map(): error preparing at_query: '%s'\n",si->at_query,0,0);
144    backsql_PrintErrors(si->db_env,dbh,at_sth,rc);
145    return -1;
146   }
147  if ((rc=backsql_BindParamID(at_sth,1,&oc_id)) != SQL_SUCCESS)
148   {
149    Debug(LDAP_DEBUG_TRACE,"load_schema_map(): error binding param for at_query: \n",0,0,0);
150    backsql_PrintErrors(si->db_env,dbh,at_sth,rc);
151    return -1;
152   }
153  if ((rc=SQLExecute(oc_sth)) != SQL_SUCCESS)
154   {
155    Debug(LDAP_DEBUG_TRACE,"load_schema_map(): error executing oc_query: \n",0,0,0);
156    backsql_PrintErrors(si->db_env,dbh,oc_sth,rc);
157    return -1;
158   }
159  backsql_BindRowAsStrings(oc_sth,&oc_row);
160  while ((rc=SQLFetch(oc_sth)) == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO)
161   {
162    oc_map=(backsql_oc_map_rec*)ch_calloc(1,sizeof(backsql_oc_map_rec));
163    oc_map->id=atoi(oc_row.cols[0]);
164    oc_map->name=ch_strdup(oc_row.cols[1]);
165    oc_map->keytbl=ch_strdup(oc_row.cols[2]);
166    oc_map->keycol=ch_strdup(oc_row.cols[3]);
167    oc_map->create_proc=(oc_row.is_null[4]<0)?NULL:ch_strdup(oc_row.cols[4]);
168    oc_map->delete_proc=(oc_row.is_null[5]<0)?NULL:ch_strdup(oc_row.cols[5]);
169    oc_map->expect_return=atoi(oc_row.cols[6]);
170
171    oc_map->attrs=NULL;
172    avl_insert(&si->oc_by_name,oc_map,(AVL_CMP)backsql_cmp_oc_name,backsql_dummy);
173    avl_insert(&si->oc_by_id,oc_map,(AVL_CMP)backsql_cmp_oc_id,backsql_dummy);
174    oc_id=oc_map->id;
175    Debug(LDAP_DEBUG_TRACE,"load_schema_map(): objectclass '%s': keytbl='%s' keycol='%s' ",
176            oc_map->name,oc_map->keytbl,oc_map->keycol);
177    if (oc_map->delete_proc) {
178      Debug(LDAP_DEBUG_TRACE,"delete_proc='%s'\n", oc_map->delete_proc, 0, 0);
179    }
180    if (oc_map->create_proc) {
181      Debug(LDAP_DEBUG_TRACE,"create_proc='%s'\n", oc_map->create_proc, 0, 0);
182    }
183    Debug(LDAP_DEBUG_TRACE,"expect_return=%d; attributes:\n",
184        oc_map->expect_return, 0, 0);
185
186    Debug(LDAP_DEBUG_TRACE,"load_schema_map(): autoadding 'objectClass' and 'ref' mappings\n",0,0,0);
187    backsql_add_sysmaps(oc_map);
188    if ((rc=SQLExecute(at_sth)) != SQL_SUCCESS)
189     {
190      Debug(LDAP_DEBUG_TRACE,"load_schema_map(): error executing at_query: \n",0,0,0);
191      backsql_PrintErrors(SQL_NULL_HENV,dbh,at_sth,rc);
192      return -1;
193     }
194    backsql_BindRowAsStrings(at_sth,&at_row);
195    while ((rc=SQLFetch(at_sth)) == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO)
196     {
197      Debug(LDAP_DEBUG_TRACE,"********'%s'\n",at_row.cols[0],0,0);
198      Debug(LDAP_DEBUG_TRACE,"name='%s',sel_expr='%s' from='%s' ",at_row.cols[0],
199              at_row.cols[1],at_row.cols[2]);
200          Debug(LDAP_DEBUG_TRACE,"join_where='%s',add_proc='%s' ",at_row.cols[3],
201              at_row.cols[4],0);
202          Debug(LDAP_DEBUG_TRACE,"delete_proc='%s'\n",at_row.cols[5],0,0);
203          Debug(LDAP_DEBUG_TRACE,"sel_expr_u='%s'\n", at_row.cols[8],0,0); /* TimesTen*/
204      at_map=(backsql_at_map_rec*)ch_calloc(1,sizeof(backsql_at_map_rec));
205      at_map->name=ch_strdup(at_row.cols[0]);
206      at_map->sel_expr=ch_strdup(at_row.cols[1]);
207          at_map->sel_expr_u = (at_row.is_null[8]<0)?NULL:ch_strdup(at_row.cols[8
208 ]);
209          tmps=NULL;tmpslen=0;
210          backsql_merge_from_clause(&tmps,&tmpslen,at_row.cols[2]);
211      at_map->from_tbls=ch_strdup(tmps);
212          ch_free(tmps);
213          at_map->join_where=ch_strdup((at_row.is_null[3]<0)?"":at_row.cols[3]);
214          at_map->add_proc=(at_row.is_null[4]<0)?NULL:ch_strdup(at_row.cols[4]);
215          at_map->delete_proc=(at_row.is_null[5]<0)?NULL:ch_strdup(at_row.cols[5]);
216          at_map->param_order=atoi(at_row.cols[6]);
217          at_map->expect_return=atoi(at_row.cols[7]);
218          backsql_make_attr_query(oc_map,at_map);
219          Debug(LDAP_DEBUG_TRACE,"load_schema_map(): preconstructed query '%s'\n",at_map->query,0,0);
220      avl_insert(&oc_map->attrs,at_map,(AVL_CMP)backsql_cmp_attr,backsql_dummy);
221     }
222    backsql_FreeRow(&at_row);
223    SQLFreeStmt(at_sth,SQL_CLOSE);
224   }
225  backsql_FreeRow(&oc_row);
226  SQLFreeStmt(at_sth,SQL_DROP);
227  SQLFreeStmt(oc_sth,SQL_DROP);
228  si->schema_loaded=1;
229  Debug(LDAP_DEBUG_TRACE,"<==load_schema_map()\n",0,0,0);
230  return 1;
231 }
232
233 backsql_oc_map_rec* backsql_oc_with_name(backsql_info *si,char* objclass)
234 {
235  backsql_oc_map_rec tmp,*res;
236  
237 /* Debug(LDAP_DEBUG_TRACE,"==>oc_with_name(): searching for objectclass with name='%s'\n",objclass,0,0);*/
238  tmp.name=objclass;
239  res=(backsql_oc_map_rec*)avl_find(si->oc_by_name,&tmp,(AVL_CMP)backsql_cmp_oc_name);
240 /* if (res!=NULL)
241   Debug(LDAP_DEBUG_TRACE,"<==oc_with_name(): found name='%s', id=%d\n",res->name,res->id,0);
242  else
243   Debug(LDAP_DEBUG_TRACE,"<==oc_with_name(): not found\n",0,0,0);
244 */
245  return res;
246 }
247
248 backsql_oc_map_rec* backsql_oc_with_id(backsql_info *si,unsigned long id)
249 {
250  backsql_oc_map_rec tmp,*res;
251  
252 /* Debug(LDAP_DEBUG_TRACE,"==>oc_with_id(): searching for objectclass with id='%d'\n",id,0,0);*/
253  tmp.id=id;
254  res=(backsql_oc_map_rec*)avl_find(si->oc_by_id,&tmp,(AVL_CMP)backsql_cmp_oc_id);
255 /* if (res!=NULL)
256   Debug(LDAP_DEBUG_TRACE,"<==oc_with_name(): found name='%s', id=%d\n",res->name,res->id,0);
257  else
258   Debug(LDAP_DEBUG_TRACE,"<==oc_with_name(): not found\n",0,0,0);
259 */
260  return res;
261 }
262
263 backsql_at_map_rec* backsql_at_with_name(backsql_oc_map_rec* objclass,char* attr)
264 {
265  backsql_at_map_rec tmp,*res;
266  
267  /*Debug(LDAP_DEBUG_TRACE,"==>at_with_name(): searching for attribute with name='%s' (for objectclass '%s')\n",
268                  attr,objclass->name,0);
269 */
270  tmp.name=attr;
271  res=(backsql_at_map_rec*)avl_find(objclass->attrs,&tmp,(AVL_CMP)backsql_cmp_attr);
272  /*if (res!=NULL)
273   Debug(LDAP_DEBUG_TRACE,"<==at_with_name(): found name='%s', sel_expr='%s'\n",
274               res->name,res->sel_expr,0);
275  else
276   Debug(LDAP_DEBUG_TRACE,"<==at_with_name(): not found\n",0,0,0);
277 */
278  return res;
279 }
280
281 int backsql_free_attr(backsql_at_map_rec *at)
282 {
283  Debug(LDAP_DEBUG_TRACE,"==>free_attr(): '%s'\n",at->name,0,0);
284  ch_free(at->name);
285  ch_free(at->sel_expr);
286  if (at->from_tbls!=NULL)
287   ch_free(at->from_tbls);
288  if (at->join_where!=NULL)
289   ch_free(at->join_where);
290  if (at->add_proc!=NULL)
291   ch_free(at->add_proc);
292  if (at->delete_proc!=NULL)
293   ch_free(at->delete_proc);
294  if (at->query)
295   ch_free(at->query);
296  ch_free(at);
297  if (at->sel_expr_u)
298    ch_free(at->sel_expr_u); /* TimesTen */
299  Debug(LDAP_DEBUG_TRACE,"<==free_attr()\n",0,0,0);
300  return 1;
301 }
302
303 int backsql_free_oc(backsql_oc_map_rec *oc)
304 {
305  Debug(LDAP_DEBUG_TRACE,"==>free_oc(): '%s'\n",oc->name,0,0);
306  avl_free(oc->attrs,(AVL_FREE)backsql_free_attr);
307  ch_free(oc->name);
308  ch_free(oc->keytbl);
309  ch_free(oc->keycol);
310  if (oc->create_proc!=NULL)
311   ch_free(oc->create_proc);
312  if (oc->delete_proc!=NULL)
313   ch_free(oc->delete_proc);
314  ch_free(oc);
315  Debug(LDAP_DEBUG_TRACE,"<==free_oc()\n",0,0,0);
316  return 1;
317 }
318
319 int backsql_destroy_schema_map(backsql_info *si)
320 {
321  Debug(LDAP_DEBUG_TRACE,"==>destroy_schema_map()\n",0,0,0);
322  avl_free(si->oc_by_id,(AVL_FREE)backsql_free_oc);
323  avl_free(si->oc_by_name,(AVL_FREE)backsql_dummy);
324  Debug(LDAP_DEBUG_TRACE,"<==destroy_schema_map()\n",0,0,0);
325  return 0;
326 }
327
328 #endif /* SLAPD_SQL */