From a16a87a41235111c2c37588f3c735c49b22f007e Mon Sep 17 00:00:00 2001 From: Dmitry Kovalev Date: Thu, 16 Mar 2000 19:46:21 +0000 Subject: [PATCH] even more back-sql files --- servers/slapd/back-sql/docs/todo | 9 ++ servers/slapd/back-sql/sql-wrap.h | 28 +++++ servers/slapd/back-sql/util.c | 163 ++++++++++++++++++++++++++++++ servers/slapd/back-sql/util.h | 51 ++++++++++ 4 files changed, 251 insertions(+) create mode 100644 servers/slapd/back-sql/docs/todo create mode 100644 servers/slapd/back-sql/sql-wrap.h create mode 100644 servers/slapd/back-sql/util.c create mode 100644 servers/slapd/back-sql/util.h diff --git a/servers/slapd/back-sql/docs/todo b/servers/slapd/back-sql/docs/todo new file mode 100644 index 0000000000..56073dd894 --- /dev/null +++ b/servers/slapd/back-sql/docs/todo @@ -0,0 +1,9 @@ +2) must add alias handling +3) must set time limit when preparing all queries, and check size limit +7) MOST important, probably - fix BUGS (see ...) +8) make an utility, which, given objectclass,name of attribute for RDN, and + base DN, adds appropriate records to ldap_entries for all data in your + RDBMS (until then, you have no automated way to fill in ldap_entries except + executing something like "insert into ldap_entries (dn,keyval,...) values + (select concat(...,) as dn,id as keyval, ... from ...)") + \ No newline at end of file diff --git a/servers/slapd/back-sql/sql-wrap.h b/servers/slapd/back-sql/sql-wrap.h new file mode 100644 index 0000000000..4669b6436a --- /dev/null +++ b/servers/slapd/back-sql/sql-wrap.h @@ -0,0 +1,28 @@ +#ifndef __BACKSQL_SQL_WRAP_H__ +#define __BACKSQL_SQL_WRAP_H__ + +/* + * Copyright 1999, Dmitry Kovalev (zmit@mail.ru), All rights reserved. + * + * Redistribution and use in source and binary forms are permitted only + * as authorized by the OpenLDAP Public License. A copy of this + * license is available at http://www.OpenLDAP.org/license.html or + * in file LICENSE in the top-level directory of the distribution. + */ + +#include "back-sql.h" +#include "sql-types.h" + +RETCODE backsql_Prepare(SQLHDBC dbh,SQLHSTMT *sth,char* query,int timeout); +RETCODE backsql_BindParamStr(SQLHSTMT sth,int par_ind,char *str,int maxlen); +RETCODE backsql_BindParamID(SQLHSTMT sth,int par_ind,unsigned long *id); +RETCODE backsql_BindRowAsStrings(SQLHSTMT sth,BACKSQL_ROW_NTS *row); +RETCODE backsql_FreeRow(BACKSQL_ROW_NTS *row); +void backsql_PrintErrors(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT sth,int rc); + +int backsql_init_db_env(backsql_info *si); +int backsql_free_db_env(backsql_info *si); +SQLHDBC backsql_get_db_conn(Backend *be,Connection *ldapc); +int backsql_free_db_conn(Backend *be,Connection *ldapc); + +#endif \ No newline at end of file diff --git a/servers/slapd/back-sql/util.c b/servers/slapd/back-sql/util.c new file mode 100644 index 0000000000..3808de31af --- /dev/null +++ b/servers/slapd/back-sql/util.c @@ -0,0 +1,163 @@ +/* + * Copyright 1999, Dmitry Kovalev (zmit@mail.ru), All rights reserved. + * + * Redistribution and use in source and binary forms are permitted only + * as authorized by the OpenLDAP Public License. A copy of this + * license is available at http://www.OpenLDAP.org/license.html or + * in file LICENSE in the top-level directory of the distribution. + */ + +#include "portable.h" + +#include +#include +#include +#include +#include "slap.h" +#include "back-sql.h" +#include "util.h" + + +char backsql_def_oc_query[]="SELECT id,name,keytbl,keycol,create_proc,delete_proc FROM ldap_objclasses"; +char backsql_def_at_query[]="SELECT name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc FROM ldap_attrs WHERE oc_id=?"; +char backsql_def_delentry_query[]="DELETE FROM ldap_entries WHERE id=?"; +char backsql_def_insentry_query[]="INSERT INTO ldap_entries (dn,objclass,parent,keyval) VALUES (?,?,?,?)"; +char backsql_def_subtree_cond[]="ldap_entries.dn LIKE CONCAT('%',?)"; + + +char* backsql_strcat(char* dest,int *buflen, ...) +{ + va_list strs; + int cdlen,cslen,grow; + char *cstr; + + //Debug(LDAP_DEBUG_TRACE,"==>my_strcat()\n"); + va_start(strs,buflen); + if (dest==NULL || *buflen<=0) + { + dest=(char*)ch_calloc(BACKSQL_STR_GROW,sizeof(char)); + *buflen=BACKSQL_STR_GROW; + } + cdlen=strlen(dest)+1; + while ((cstr=va_arg(strs,char*)) != NULL) + { + cslen=strlen(cstr); + grow=BACKSQL_MAX(BACKSQL_STR_GROW,cslen); + if (*buflen-cdlen < cslen) + { + //Debug(LDAP_DEBUG_TRACE,"my_strcat(): buflen=%d, cdlen=%d, cslen=%d -- reallocating dest\n", + // *buflen,cdlen,cslen); + dest=(char*)ch_realloc(dest,(*buflen)+grow*sizeof(char)); + if (dest == NULL) + { + Debug(LDAP_DEBUG_ANY,"my_strcat(): could not reallocate string buffer.\n",0,0,0); + } + *buflen+=grow; + //Debug(LDAP_DEBUG_TRACE,"my_strcat(): new buflen=%d, dest=%p\n",*buflen,dest,0); + } + strcat(dest,cstr); + cdlen+=cslen; + } + va_end(strs); + //Debug(LDAP_DEBUG_TRACE,"<==my_strcat() (dest='%s')\n",dest,0,0); + return dest; +} + +int backsql_entry_addattr(Entry *e,char *at_name,char *at_val,unsigned int at_val_len) +{ + Attribute *c_at=e->e_attrs; + struct berval **cval; + int nvals; + + Debug(LDAP_DEBUG_TRACE,"backsql_entry_addattr(): at_name='%s', at_val='%s'\n",at_name,at_val,0); + while (c_at!=NULL && strcasecmp(c_at->a_type,at_name)) + c_at=c_at->a_next; + if (c_at == NULL) + { + //Debug(LDAP_DEBUG_TRACE,"backsql_addattr(): creating new attribute\n",0,0,0); + c_at=(Attribute *)ch_calloc(sizeof(Attribute),1); + c_at->a_type=strdup(at_name); + c_at->a_syntax=SYNTAX_CIS; + c_at->a_vals=(struct berval**)ch_calloc(sizeof(struct berval *),1); + c_at->a_vals[0]=NULL; + c_at->a_next=e->e_attrs; + e->e_attrs=c_at; + } + //Debug(LDAP_DEBUG_TRACE,"backsql_addattr(): checking attribute values\n",0,0,0); + //should use different comparison methods for different attributes + //for now, uses memcmp + for (cval=c_at->a_vals,nvals=0;*cval != NULL && + memcmp((*cval)->bv_val,at_val,BACKSQL_MIN((*cval)->bv_len,at_val_len));cval++,nvals++); + + if (*cval==NULL) + { + //Debug(LDAP_DEBUG_TRACE,"backsql_addattr(): nvals=%d; adding new value\n",nvals,0,0); + c_at->a_vals=(struct berval **)realloc(c_at->a_vals,sizeof(struct berval *)*(nvals+2)); + c_at->a_vals[nvals]=(struct berval*)ch_calloc(sizeof(struct berval),1); + c_at->a_vals[nvals]->bv_val=(char*)ch_calloc(sizeof(char),at_val_len); + strncpy(c_at->a_vals[nvals]->bv_val,at_val,at_val_len); + c_at->a_vals[nvals]->bv_len=at_val_len; + c_at->a_vals[nvals+1]=NULL; + } + else + { + //Debug(LDAP_DEBUG_TRACE,"backsql_addattr(): value already exists\n",0,0,0); + } + Debug(LDAP_DEBUG_TRACE,"<==backsql_query_addattr()\n",0,0,0); + return 1; +} + +char* backsql_get_table_spec(char **p) +{ + char *s,*q; + char *res=NULL; + int res_len=0; + + s=*p; + while(**p && **p!=',') (*p)++; + if (**p) + *(*p)++='\0'; + +#define BACKSQL_NEXT_WORD {while (*s && isspace(*s)) s++; if (!*s) return res; q=s; while (*q && !isspace(*q)) q++; if (*q) *q++='\0';} + BACKSQL_NEXT_WORD; + res=backsql_strcat(res,&res_len,s,NULL);//table name + s=q; + + BACKSQL_NEXT_WORD; + if (!strcasecmp(s,"as")) + { + s=q; + BACKSQL_NEXT_WORD; + } + //res=backsql_strcat(res,&res_len," AS ",s,NULL);//table alias + //oracle doesn't understand AS :( + res=backsql_strcat(res,&res_len," ",s,NULL);//table alias + return res; +} + +int backsql_merge_from_clause(char **dest_from,int *dest_len,char *src_from) +{ + char *s,*p,*srcc,*pos,e; + + //Debug(LDAP_DEBUG_TRACE,"==>backsql_merge_from_clause(): dest_from='%s',src_from='%s'\n", + // dest_from,src_from,0); + srcc=strdup(src_from); + p=srcc; + while(*p) + {//4832041 + s=backsql_get_table_spec(&p); + // Debug(LDAP_DEBUG_TRACE,"backsql_merge_from_clause(): p='%s' s='%s'\n",p,s,0); + if (*dest_from==NULL) + *dest_from=backsql_strcat(*dest_from,dest_len,s,NULL); + else + if((pos=strstr(*dest_from,s))==NULL) + *dest_from=backsql_strcat(*dest_from,dest_len,",",s,NULL); + else if((e=pos[strlen(s)])!='\0' && e!=',') + *dest_from=backsql_strcat(*dest_from,dest_len,",",s,NULL); + if (s) + ch_free(s); + } +// Debug(LDAP_DEBUG_TRACE,"<==backsql_merge_from_clause()\n",0,0,0); + free(srcc); + return 1; +} diff --git a/servers/slapd/back-sql/util.h b/servers/slapd/back-sql/util.h new file mode 100644 index 0000000000..b3e8bd23a4 --- /dev/null +++ b/servers/slapd/back-sql/util.h @@ -0,0 +1,51 @@ +#ifndef __BACKSQL_UTIL_H__ +#define __BACKSQL_UTIL_H__ + + +#include "entry-id.h" +#include "schema-map.h" + +#define BACKSQL_MAX(a,b) ((a)>(b)?(a):(b)) +#define BACKSQL_MIN(a,b) ((a)<(b)?(a):(b)) + +#define BACKSQL_STR_GROW 64 + +char* backsql_strcat(char* dest,int *buflen, ...); + +int backsql_entry_addattr(Entry *e,char *at_name,char *at_val,unsigned int at_val_len); + +typedef struct __backsql_srch_info +{ + char *base_dn; + int scope; + Filter *filter; + int slimit,tlimit; + time_t stoptime; + backsql_entryID *id_list,*c_eid; + int abandon; + backsql_info *bi; + backsql_oc_map_rec *oc; + char *sel,*from,*join_where,*flt_where; + int sel_len,from_len,jwhere_len,fwhere_len; + SQLHDBC dbh; + int status; + Backend *be; + Connection *conn; + Operation *op; + char **attrs; + Entry *e; +}backsql_srch_info; + +int backsql_process_filter(backsql_srch_info *bsi,Filter *f); +void backsql_init_search(backsql_srch_info *bsi,backsql_info *bi,char *nbase,int scope, + int slimit,int tlimit,time_t stoptime,Filter *filter, + SQLHDBC dbh,Backend *be,Connection *conn,Operation *op,char **attrs); +Entry* backsql_id2entry(backsql_srch_info *bsi,Entry* e,backsql_entryID* id); + +extern char backsql_def_oc_query[],backsql_def_at_query[], + backsql_def_delentry_query[],backsql_def_insentry_query[], + backsql_def_subtree_cond[]; + +int backsql_merge_from_clause(char **dest_from,int *dest_len,char *src_from); + +#endif \ No newline at end of file -- 2.39.5