#define __BACKSQL_H__
/*
- * Copyright 1999, Dmitry Kovalev (zmit@mail.ru), All rights reserved.
+ * Copyright 1999, Dmitry Kovalev <mit@openldap.org>, 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
char *subtree_cond;
char *oc_query,*at_query;
char *insentry_query,*delentry_query;
+ char *id_query;
+ char *upper_func;
Avlnode *db_conns;
Avlnode *oc_by_name;
Avlnode *oc_by_id;
/*
- * Copyright 1999, Dmitry Kovalev (zmit@mail.ru), All rights reserved.
+ * Copyright 1999, Dmitry Kovalev <mit@openldap.org>, 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
#include "back-sql.h"
#include "sql-wrap.h"
-int backsql_bind(Backend *be,Connection *conn,Operation *op,
- char *dn,char *ndn,int method,struct berval *cred,char** edn)
+int backsql_bind(BackendDB *be,Connection *conn,Operation *op,
+ const char *dn,const char *ndn,int method,struct berval *cred,char** edn)
{
Debug(LDAP_DEBUG_TRACE,"==>backsql_bind()\n",0,0,0);
//for now, just return OK, allowing to test modify operations
return 0;
}
-int backsql_unbind(Backend *be,Connection *conn,Operation *op)
+int backsql_unbind(BackendDB *be,Connection *conn,Operation *op)
{
Debug(LDAP_DEBUG_TRACE,"==>backsql_unbind()\n",0,0,0);
backsql_free_db_conn(be,conn);
/*
- * Copyright 1999, Dmitry Kovalev (zmit@mail.ru), All rights reserved.
+ * Copyright 1999, Dmitry Kovalev <mit@openldap.org>, 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
}
else
{
- si->dbhost=strdup(argv[1]);
+ si->dbhost=ch_strdup(argv[1]);
Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config(): hostname=%s\n",si->dbhost,0,0);
}
return(0);
}
else
{
- si->dbuser=strdup(argv[1]);
+ si->dbuser=ch_strdup(argv[1]);
Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config(): dbuser=%s\n",argv[1],0,0);
}
return(0);
}
else
{
- si->dbpasswd=strdup(argv[1]);
+ si->dbpasswd=ch_strdup(argv[1]);
Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config(): dbpasswd=%s\n",si->dbpasswd,0,0);
}
return(0);
}
else
{
- si->dbname=strdup(argv[1]);
+ si->dbname=ch_strdup(argv[1]);
Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config(): dbname=%s\n",si->dbname,0,0);
}
return(0);
}
else
{
- si->subtree_cond=strdup(argv[1]);
+ si->subtree_cond=ch_strdup(argv[1]);
Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config(): subtree_cond=%s\n",si->subtree_cond,0,0);
}
return(0);
}
else
{
- si->oc_query=strdup(argv[1]);
+ si->oc_query=ch_strdup(argv[1]);
Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config(): oc_query=%s\n",si->oc_query,0,0);
}
return(0);
}
else
{
- si->at_query=strdup(argv[1]);
+ si->at_query=ch_strdup(argv[1]);
Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config(): at_query=%s\n",si->at_query,0,0);
}
return(0);
}
else
{
- si->insentry_query=strdup(argv[1]);
+ si->insentry_query=ch_strdup(argv[1]);
Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config(): insentry_query=%s\n",si->insentry_query,0,0);
}
return(0);
}
+ if (!strcasecmp(argv[0],"upper_func"))
+ {
+ if (argc<2)
+ {
+ Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config (%s line %d): missing function name in upper_func directive\n",
+ fname,lineno,0);
+ }
+ else
+ {
+ si->upper_func=ch_strdup(argv[1]);
+ Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config(): upper_func=%s\n",si->upper_func,0,0);
+ }
+ return(0);
+ }
+
if (!strcasecmp(argv[0],"delentry_query"))
{
if (argc<2)
}
else
{
- si->delentry_query=strdup(argv[1]);
+ si->delentry_query=ch_strdup(argv[1]);
Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config(): delentry_query=%s\n",si->delentry_query,0,0);
}
return(0);
fname,lineno,argv[0]);
return 0;
}
-#endif /* SLAPD_SQL */
\ No newline at end of file
+
+#endif /* SLAPD_SQL */
6.1 (glibc 2.1.2) (the same code behaves differently when built on 6.0 and 6.1)
my problem was solved by upgrading iODBC to 3.0 beta - but it is kinda strange
that beta works better than release (and release still works fine on 6.0)
-8) Oracle does case-sensitive comparison of strings by default, so back-sql
- becomes sensitive too when using Oracle. Later I'll add some option to slapd.conf
- that would allow to set some function to process values before comparison
- (something like "before_match UPPER", so that back-sql could generate
- something like "select ... from ... where ... and UPPER(colname)=UPPER(?) or
- UPPER(colname) LIKE UPPER(...)")
9) ldapsearch sometimes refuses to show some attributes ("NOT PRINTABLE" diags)
on Win32 (on linux everything's fine -- at least with mySQL)
\ No newline at end of file
1. Build
To build slapd with back-sql under Unix you need to build and install
iODBC 2.50.3 (later versions should probably work). Then, run
-"configure <options you need> --enable-sql [--with-iodbc-includes=<path>] [--with-iodbc-libs=<path>]",
-this should build back-sql-enabled slapd.
+"configure <other options you need> --enable-sql",
+this should build back-sql-enabled slapd, provided that you have iODBC
+libraries and include files in include/library paths.
Under Win32/MSVC++, I modified the workspace so that back-sql is built into
slapd automatically, since MS odbc32 is included in standard library pack,
and it does no bad even if you don't plan to use it. I also could provide
-precompiled executables for those who don't have MSVC later (when back-sql
-comes into some stable state).
+precompiled executables for those who don't have MSVC.
2. Tune datasources and slapd.conf
Next, you need to define ODBC datasource with data you want to publish
/*
- * Copyright 1999, Dmitry Kovalev (zmit@mail.ru), All rights reserved.
+ * Copyright 1999, Dmitry Kovalev <mit@openldap.org>, 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
return next;
}
-backsql_entryID* backsql_dn2id(backsql_entryID *id,SQLHDBC dbh,char *dn)
+backsql_entryID* backsql_dn2id(backsql_info *bi,backsql_entryID *id,SQLHDBC dbh,char *dn)
{
- static char id_query[]="SELECT id,keyval,objclass FROM ldap_entries WHERE dn=?";
SQLHSTMT sth;
BACKSQL_ROW_NTS row;
//SQLINTEGER nrows=0;
RETCODE rc;
Debug(LDAP_DEBUG_TRACE,"==>backsql_dn2id(): dn='%s'\n",dn,0,0);
- backsql_Prepare(dbh,&sth,id_query,0);
+ backsql_Prepare(dbh,&sth,bi->id_query,0);
if ((rc=backsql_BindParamStr(sth,1,dn,BACKSQL_MAX_DN_LEN)) != SQL_SUCCESS)
{
Debug(LDAP_DEBUG_TRACE,"backsql_dn2id(): error binding dn parameter:\n",0,0,0);
id->id=atoi(row.cols[0]);
id->keyval=atoi(row.cols[1]);
id->oc_id=atoi(row.cols[2]);
- id->dn=strdup(dn);
+ id->dn=ch_strdup(dn);
id->next=NULL;
}
else
bsi->c_eid=eid;
e->e_attrs=NULL;
if (bsi->base_dn != NULL)
- e->e_dn=strdup(bsi->c_eid->dn);
+ e->e_dn=ch_strdup(bsi->c_eid->dn);
if (bsi->attrs!=NULL)
{
return e;
}
-#endif /* SLAPD_SQL */
\ No newline at end of file
+#endif /* SLAPD_SQL */
#ifndef __BACKSQL_ENTRYID_H__
#define __BACKSQL_ENTRYID_H__
+/*
+ * Copyright 1999, Dmitry Kovalev <mit@openldap.org>, 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.
+ */
+
+
typedef struct __backsql_entryID
{
unsigned long id;
struct __backsql_entryID *next;
}backsql_entryID;
-backsql_entryID* backsql_dn2id(backsql_entryID* id,SQLHDBC dbh,char *dn);
+backsql_entryID* backsql_dn2id(backsql_info *bi,backsql_entryID* id,SQLHDBC dbh,char *dn);
backsql_entryID* backsql_free_entryID(backsql_entryID* id);//returns next
#endif
\ No newline at end of file
#ifndef _SQL_EXTERNAL_H
#define _SQL_EXTERNAL_H
+/*
+ * Copyright 1999, Dmitry Kovalev <mit@openldap.org>, 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.
+ */
+
+
LDAP_BEGIN_DECL
extern int sql_back_initialize LDAP_P(( BackendInfo *bi ));
/*
- * Copyright 1999, Dmitry Kovalev (zmit@mail.ru), All rights reserved.
+ * Copyright 1999, Dmitry Kovalev <mit@openldap.org>, 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
free(si->dbpasswd);
if (si->dbhost)
free(si->dbhost);
+ if (si->upper_func)
+ free(si->upper_func);
free(si->subtree_cond);
free(si->oc_query);
free(si->at_query);
backsql_info *si=(backsql_info*)bd->be_private;
Connection tmp;
SQLHDBC dbh;
+ int idq_len;
Debug(LDAP_DEBUG_TRACE,"==>backsql_db_open(): testing RDBMS connection\n",0,0,0);
if (si->dbname==NULL)
{
Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): subtree search SQL condition not specified (use subtree_cond directive in slapd.conf)\n",0,0,0);
Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): setting '%s' as default\n",backsql_def_subtree_cond,0,0);
- si->subtree_cond=strdup(backsql_def_subtree_cond);
+ si->subtree_cond=ch_strdup(backsql_def_subtree_cond);
}
if (si->oc_query==NULL)
{
Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): objectclass mapping SQL statement not specified (use oc_query directive in slapd.conf)\n",0,0,0);
Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): setting '%s' by default\n",backsql_def_oc_query,0,0);
- si->oc_query=strdup(backsql_def_oc_query);
+ si->oc_query=ch_strdup(backsql_def_oc_query);
}
if (si->at_query==NULL)
{
Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): attribute mapping SQL statement not specified (use at_query directive in slapd.conf)\n",0,0,0);
Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): setting '%s' by default\n",backsql_def_at_query,0,0);
- si->at_query=strdup(backsql_def_at_query);
+ si->at_query=ch_strdup(backsql_def_at_query);
}
if (si->insentry_query==NULL)
{
Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): entry insertion SQL statement not specified (use insentry_query directive in slapd.conf)\n",0,0,0);
Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): setting '%s' by default\n",backsql_def_insentry_query,0,0);
- si->insentry_query=strdup(backsql_def_insentry_query);
+ si->insentry_query=ch_strdup(backsql_def_insentry_query);
}
if (si->delentry_query==NULL)
{
Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): entry deletion SQL statement not specified (use delentry_query directive in slapd.conf)\n",0,0,0);
Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): setting '%s' by default\n",backsql_def_delentry_query,0,0);
- si->delentry_query=strdup(backsql_def_delentry_query);
+ si->delentry_query=ch_strdup(backsql_def_delentry_query);
}
+ si->id_query=NULL;
+ idq_len=0;
+ if (si->upper_func==NULL)
+ {
+ si->id_query=backsql_strcat(si->id_query,&idq_len,backsql_id_query,"dn=?",NULL);
+ }
+ else
+ {
+ si->id_query=backsql_strcat(si->id_query,&idq_len,backsql_id_query,si->upper_func,"(dn)=",si->upper_func,"(?)",NULL);
+ }
tmp.c_connid=-1;
dbh=backsql_get_db_conn(bd,&tmp);
if (!dbh)
return 1;
}
backsql_free_db_conn(bd,&tmp);
+ if (!si->schema_loaded)
+ {
+ Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): test failed, schema map not loaded - exiting\n",0,0,0);
+ return 1;
+ }
Debug(LDAP_DEBUG_TRACE,"<==backsql_db_open(): test succeeded, schema map loaded\n",0,0,0);
return 0;
}
return 0;
}
-#endif /* SLAPD_SQL */
\ No newline at end of file
+#endif /* SLAPD_SQL */
/*
- * Copyright 1999, Dmitry Kovalev (zmit@mail.ru), All rights reserved.
+ * Copyright 1999, Dmitry Kovalev <mit@openldap.org>, 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
#include "util.h"
int backsql_modify(BackendDB *be,Connection *conn,Operation *op,
- char *dn,char *ndn,LDAPModList *modlist)
+ const char *dn,const char *ndn,LDAPModList *modlist)
{
backsql_info *bi=(backsql_info*)be->be_private;
SQLHDBC dbh;
backsql_at_map_rec *at=NULL;
struct berval *at_val;
int i;
+ int pno,po;//first parameter no, parameter order
+ int prc; //procedure return code
- dn=dn_validate(dn);
- Debug(LDAP_DEBUG_TRACE,"==>backsql_modify(): changing entry '%s'\n",dn,0,0);
+ Debug(LDAP_DEBUG_TRACE,"==>backsql_modify(): changing entry '%s'\n",ndn,0,0);
dbh=backsql_get_db_conn(be,conn);
if (!dbh)
{
send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
return 1;
}
- res=backsql_dn2id(&e_id,dbh,dn);
+ res=backsql_dn2id(bi,&e_id,dbh,(char*)ndn);
if (res==NULL)
{
Debug(LDAP_DEBUG_TRACE,"backsql_modify(): could not lookup entry id\n",0,0,0);
at=backsql_at_with_name(oc,c_mod->ml_type);
if (at==NULL)
{
- Debug(LDAP_DEBUG_TRACE,"backsql_add(): attribute provided is not registered in this objectclass ('%s')\n",c_mod->ml_type,0,0);
+ Debug(LDAP_DEBUG_TRACE,"backsql_modify(): attribute provided is not registered in this objectclass ('%s')\n",c_mod->ml_type,0,0);
continue;
}
- SQLBindParameter(sth,1,SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.keyval,0,0);
+
switch(c_mod->ml_op)
{
case LDAP_MOD_REPLACE:
{
- char *query;
- int qlen;
SQLHSTMT asth;
BACKSQL_ROW_NTS row;
break;
}
del_all:
- query=NULL;
- qlen=0;
- query=backsql_strcat(query,&qlen,"SELECT ",at->sel_expr," AS ",at->name,
- " FROM ",at->from_tbls,
- " WHERE ",oc->keytbl,".",oc->keycol,"=?",NULL);
- if (at->join_where!=NULL && at->join_where[0]!='\0')
- query=backsql_strcat(query,&qlen," AND ",at->join_where,NULL);
-
- Debug(LDAP_DEBUG_TRACE,"backsql_modify() constructed query to get all existing values: %s\n",query,0,0);
- if ((rc=backsql_Prepare(dbh,&asth,query,0)) != SQL_SUCCESS)
+
+ if ((rc=backsql_Prepare(dbh,&asth,at->query,0)) != SQL_SUCCESS)
{
- Debug(LDAP_DEBUG_TRACE,"backsql_get_attr_values(): error preparing query\n",0,0,0);
+ Debug(LDAP_DEBUG_TRACE,"backsql_modify(): error preparing query\n",0,0,0);
backsql_PrintErrors(bi->db_env,dbh,asth,rc);
- free(query);
break;
}
- free(query);
if (backsql_BindParamID(asth,1,&e_id.keyval) != SQL_SUCCESS)
{
- Debug(LDAP_DEBUG_TRACE,"backsql_get_attr_values(): error binding key value parameter\n",0,0,0);
+ Debug(LDAP_DEBUG_TRACE,"backsql_modify(): error binding key value parameter\n",0,0,0);
backsql_PrintErrors(bi->db_env,dbh,asth,rc);
SQLFreeStmt(asth,SQL_DROP);
break;
if ((rc=SQLExecute(asth)) != SQL_SUCCESS && rc!= SQL_SUCCESS_WITH_INFO)
{
- Debug(LDAP_DEBUG_TRACE,"backsql_get_attr_values(): error executing attribute query\n",0,0,0);
+ Debug(LDAP_DEBUG_TRACE,"backsql_modify(): error executing attribute query\n",0,0,0);
backsql_PrintErrors(bi->db_env,dbh,asth,rc);
SQLFreeStmt(asth,SQL_DROP);
break;
{
for (i=0;i<row.ncols;i++)
{
- SQLBindParameter(sth,2,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,0,0,row.cols[i],strlen(row.cols[i]),0);
+ if (at->expect_return & BACKSQL_DEL)
+ {
+ pno=1;
+ SQLBindParameter(sth,1,SQL_PARAM_OUTPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&prc,0,0);
+ }
+ else
+ pno=0;
+ po=(at->param_order & BACKSQL_DEL)>0;
+ SQLBindParameter(sth,(SQLUSMALLINT)(pno+1+po),SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.keyval,0,0);
+ //check for syntax needed here - maybe need binary bind?
+ SQLBindParameter(sth,(SQLUSMALLINT)(pno+2-po),SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,0,0,row.cols[i],strlen(row.cols[i]),0);
+
Debug(LDAP_DEBUG_TRACE,"backsql_modify(): executing '%s'\n",at->delete_proc,0,0);
rc=SQLExecDirect(sth,at->delete_proc,SQL_NTS);
if (rc!=SQL_SUCCESS)
Debug(LDAP_DEBUG_TRACE,"backsql_modify(): adding new values for attribute '%s'\n",at->name,0,0);
for(i=0,at_val=c_mod->ml_bvalues[0];at_val!=NULL;i++,at_val=c_mod->ml_bvalues[i])
{
- //check for syntax here - maybe need binary bind?
- SQLBindParameter(sth,2,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,0,0,at_val->bv_val,at_val->bv_len,0);
+ if (at->expect_return & BACKSQL_ADD)
+ {
+ pno=1;
+ SQLBindParameter(sth,1,SQL_PARAM_OUTPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&prc,0,0);
+ }
+ else
+ pno=0;
+ po=(at->param_order & BACKSQL_ADD)>0;
+ SQLBindParameter(sth,(SQLUSMALLINT)(pno+1+po),SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.keyval,0,0);
+ //check for syntax needed here - maybe need binary bind?
+ SQLBindParameter(sth,(SQLUSMALLINT)(pno+2-po),SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,0,0,at_val->bv_val,at_val->bv_len,0);
+
Debug(LDAP_DEBUG_TRACE,"backsql_modify(): executing '%s'\n",at->add_proc,0,0);
rc=SQLExecDirect(sth,at->add_proc,SQL_NTS);
if (rc!=SQL_SUCCESS)
Debug(LDAP_DEBUG_TRACE,"backsql_modify(): deleting values for attribute '%s'\n",at->name,0,0);
for(i=0,at_val=c_mod->ml_bvalues[0];at_val!=NULL;i++,at_val=c_mod->ml_bvalues[i])
{
- //check for syntax here - maybe need binary bind?
- SQLBindParameter(sth,2,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,0,0,at_val->bv_val,at_val->bv_len,0);
+ if (at->expect_return & BACKSQL_DEL)
+ {
+ pno=1;
+ SQLBindParameter(sth,1,SQL_PARAM_OUTPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&prc,0,0);
+ }
+ else
+ pno=0;
+ po=(at->param_order & BACKSQL_DEL)>0;
+ SQLBindParameter(sth,(SQLUSMALLINT)(pno+1+po),SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.keyval,0,0);
+ //check for syntax needed here - maybe need binary bind?
+ SQLBindParameter(sth,(SQLUSMALLINT)(pno+2-po),SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,0,0,at_val->bv_val,at_val->bv_len,0);
+
Debug(LDAP_DEBUG_TRACE,"backsql_modify(): executing '%s'\n",at->delete_proc,0,0);
rc=SQLExecDirect(sth,at->delete_proc,SQL_NTS);
if (rc!=SQL_SUCCESS)
}
int backsql_modrdn(BackendDB *be,Connection *conn,Operation *op,
- char *dn,char *ndn,char *newrdn,int deleteoldrdn,char *newSuperior)
+ const char *dn,const char *ndn,const char *newrdn,int deleteoldrdn,const char *newSuperior)
{
Debug(LDAP_DEBUG_TRACE,"==>backsql_modrdn()\n",0,0,0);
return 0;
Attribute *at;
struct berval *at_val;
char *pdn;
+ int pno,po;//first parameter no, parameter order
+ int prc; //procedure return code
Debug(LDAP_DEBUG_TRACE,"==>backsql_add(): adding entry '%s'\n",e->e_dn,0,0);
if (dn_validate(e->e_dn)==NULL)
SQLAllocStmt(dbh, &sth);
SQLBindParameter(sth,1,SQL_PARAM_OUTPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&new_keyval,0,0);
- //SQLBindParameter(sth,2,SQL_PARAM_OUTPUT,SQL_C_SLONG,SQL_INTEGER,0,0,&retcode,0,0);
Debug(LDAP_DEBUG_TRACE,"backsql_add(): executing '%s'\n",oc->create_proc,0,0);
rc=SQLExecDirect(sth,oc->create_proc,SQL_NTS);
Debug(LDAP_DEBUG_TRACE,"backsql_add(): add procedure is not defined for this attribute ('%s')\n",at->a_type,0,0);
continue;
}
- SQLBindParameter(sth,1,SQL_PARAM_INPUT,SQL_C_LONG,SQL_INTEGER,0,0,&new_keyval,0,0);
+
for(i=0,at_val=at->a_vals[0];at_val!=NULL;i++,at_val=at->a_vals[i])
{
- //if (at->a_syntax==SYNTAX_BIN)
- // SQLBindParameter(sth,2,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_BINARY,0,0,at_val->bv_val,0,0);
- //else
- SQLBindParameter(sth,2,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,0,0,at_val->bv_val,at_val->bv_len,0);
+ if (at_rec->expect_return & BACKSQL_ADD)
+ {
+ pno=1;
+ SQLBindParameter(sth,1,SQL_PARAM_OUTPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&prc,0,0);
+ }
+ else
+ pno=0;
+ po=(at_rec->param_order & BACKSQL_ADD)>0;
+ SQLBindParameter(sth,(SQLUSMALLINT)(pno+1+po),SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&new_keyval,0,0);
+ //check for syntax needed here - maybe need binary bind?
+ SQLBindParameter(sth,(SQLUSMALLINT)(pno+2-po),SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,0,0,at_val->bv_val,at_val->bv_len,0);
Debug(LDAP_DEBUG_TRACE,"backsql_add(): executing '%s'\n",at_rec->add_proc,0,0);
rc=SQLExecDirect(sth,at_rec->add_proc,SQL_NTS);
if (rc!=SQL_SUCCESS)
}
SQLFreeStmt(sth,SQL_RESET_PARAMS);
pdn=dn_parent(be,e->e_dn);
- res=backsql_dn2id(&parent_id,dbh,pdn);
+ res=backsql_dn2id(bi,&parent_id,dbh,pdn);
if (res==NULL)
{
Debug(LDAP_DEBUG_TRACE,"backsql_add(): could not lookup parent entry for new record ('%s')\n",
}
int backsql_delete(BackendDB *be,Connection *conn,Operation *op,
- char *dn,char *ndn)
+ const char *dn,const char *ndn)
{
backsql_info *bi=(backsql_info*)be->be_private;
SQLHDBC dbh;
RETCODE rc;
backsql_oc_map_rec *oc=NULL;
backsql_entryID e_id,*res;
+ int pno;//first parameter no, parameter order
- dn=dn_validate(dn);
- Debug(LDAP_DEBUG_TRACE,"==>backsql_delete(): deleting entry '%s'\n",dn,0,0);
+ Debug(LDAP_DEBUG_TRACE,"==>backsql_delete(): deleting entry '%s'\n",ndn,0,0);
dbh=backsql_get_db_conn(be,conn);
if (!dbh)
{
send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
return 1;
}
- res=backsql_dn2id(&e_id,dbh,dn);
+ res=backsql_dn2id(bi,&e_id,dbh,(char*)ndn);
if (res==NULL)
{
Debug(LDAP_DEBUG_TRACE,"backsql_delete(): could not lookup entry id\n",0,0,0);
}
SQLAllocStmt(dbh, &sth);
- SQLBindParameter(sth,1,SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.keyval,0,0);
+ if (oc->expect_return)
+ {
+ pno=1;
+ SQLBindParameter(sth,1,SQL_PARAM_OUTPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&rc,0,0);
+ }
+ else
+ pno=0;
+ SQLBindParameter(sth,(SQLUSMALLINT)(pno+1),SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.keyval,0,0);
//SQLBindParameter(sth,2,SQL_PARAM_OUTPUT,SQL_C_SLONG,SQL_INTEGER,0,0,&retcode,0,0);
Debug(LDAP_DEBUG_TRACE,"backsql_delete(): executing '%s'\n",oc->delete_proc,0,0);
return 0;
}
-#endif /* SLAPD_SQL */
\ No newline at end of file
+#endif /* SLAPD_SQL */
/*
- * Copyright 1999, Dmitry Kovalev (zmit@mail.ru), All rights reserved.
+ * Copyright 1999, Dmitry Kovalev <mit@openldap.org>, 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
}
int backsql_compare(BackendDB *be,Connection *conn,Operation *op,
- char *dn,char *ndn,Ava *ava)
+ const char *dn,const char *ndn,Ava *ava)
{
Debug(LDAP_DEBUG_TRACE,"==>backsql_compare()\n",0,0,0);
return 0;
return 0;
}
-#endif /* SLAPD_SQL */
\ No newline at end of file
+#endif /* SLAPD_SQL */
join_where varchar (255) NULL ,
add_proc varchar (255) NULL ,
modify_proc varchar (255) NULL ,
- delete_proc varchar (255) NULL
+ delete_proc varchar (255) NULL ,
+ param_order int NOT NULL,
+ expect_return int NOT NULL
)
GO
keytbl varchar (64) NOT NULL ,
keycol varchar (64) NOT NULL ,
create_proc varchar (255) NULL ,
- delete_proc varchar (255) NULL
+ delete_proc varchar (255) NULL,
+ expect_return int NOT NULL
)
GO
SET IDENTITY_INSERT ldap_objclasses ON
-insert into ldap_objclasses (id,name,keytbl,keycol,create_proc,delete_proc)
-values (1,'person','persons','id','{call create_person(?)}','{call delete_person(?)}')
+insert into ldap_objclasses (id,name,keytbl,keycol,create_proc,delete_proc,expect_return)
+values (1,'person','persons','id','{call create_person(?)}','{call delete_person(?)}',0)
-insert into ldap_objclasses (id,name,keytbl,keycol,create_proc,delete_proc)
-values (2,'document','documents','id','{call create_document(?)}','{call delete_document(?)}')
+insert into ldap_objclasses (id,name,keytbl,keycol,create_proc,delete_proc,expect_return)
+values (2,'document','documents','id','{call create_document(?)}','{call delete_document(?)}',0)
-insert into ldap_objclasses (id,name,keytbl,keycol,create_proc,delete_proc)
-values (3,'organization','institutes','id','{call create_org(?)}','{call delete_org(?)}')
+insert into ldap_objclasses (id,name,keytbl,keycol,create_proc,delete_proc,expect_return)
+values (3,'organization','institutes','id','{call create_org(?)}','{call delete_org(?)}',0)
SET IDENTITY_INSERT ldap_objclasses OFF
SET IDENTITY_INSERT ldap_attrs ON
-insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc)
+insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return)
values (1,1,'cn','persons.name','persons',NULL,'{call set_person_name(?,?)}',
- NULL,NULL)
+ NULL,NULL,0,0)
-insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc)
+insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return)
values (2,1,'telephoneNumber','phones.phone','persons,phones',
'phones.pers_id=persons.id','{call add_phone(?,?)}',
- NULL,'{call delete_phone(?,?)}')
+ NULL,'{call delete_phone(?,?)}',0,0)
-insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc)
+insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return)
values (3,1,'sn','persons.name','persons',NULL,'{call set_person_name(?,?)}',
- NULL,NULL)
+ NULL,NULL,0,0)
-insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc)
+insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return)
values (4,2,'abstract','documents.abstract','documents',NULL,'{call set_doc_abstract(?,?)}',
- NULL,NULL)
-
-insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc)
+ NULL,NULL,0,0)
+
+insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return)
values (5,2,'documentTitle','documents.title','documents',NULL,'{call set_doc_title(?,?)}',
- NULL,NULL)
+ NULL,NULL,0,0)
-insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc)
+insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return)
values (6,2,'documentAuthor','persons.name','persons,documents,authors_docs',
'persons.id=authors_docs.pers_id AND documents.id=authors_docs.doc_id',
- NULL,NULL,NULL)
+ NULL,NULL,NULL,0,0)
-insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc)
+insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return)
values (7,3,'o','institutes.name','institutes',NULL,'{call set_org_name(?,?)}',
- NULL,NULL)
+ NULL,NULL,0,0)
-insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc)
+insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return)
values (8,1,'documentDN','ldap_entries.dn','ldap_entries,documents,authors_docs,persons',
'ldap_entries.keyval=documents.id AND ldap_entries.objclass=2 AND authors_docs.doc_id=documents.id AND authors_docs.pers_id=persons.id',
- '{call make_doc_link(?,?)}',NULL,'{call del_doc_link(?,?)}')
+ '{call make_doc_link(?,?)}',NULL,'{call del_doc_link(?,?)}',0,0)
-insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc)
+insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return)
values (9,2,'authorDN','ldap_entries.dn','ldap_entries,documents,authors_docs,persons',
'ldap_entries.keyval=persons.id AND ldap_entries.objclass=1 AND authors_docs.doc_id=documents.id AND authors_docs.pers_id=persons.id',
- '{call make_author_link(?,?)}',NULL,'{call del_author_link(?,?)}')
+ '{call make_author_link(?,?)}',NULL,'{call del_author_link(?,?)}',0,0)
SET IDENTITY_INSERT ldap_attrs OFF
join_where varchar(255),
add_proc varchar(255),
modify_proc varchar(255),
- delete_proc varchar(255)
+ delete_proc varchar(255),
+ param_order tinyint NOT NULL,
+ expect_return tinyint NOT NULL
);
keytbl varchar(64) NOT NULL ,
keycol varchar(64) NOT NULL ,
create_proc varchar(255),
- delete_proc varchar(255)
+ delete_proc varchar(255),
+ expect_return tinyint NOT NULL
);
ALTER TABLE ldap_entries ADD
-insert into ldap_objclasses (id,name,keytbl,keycol,create_proc,delete_proc)
-values (1,'person','persons','id',NULL,NULL);
+insert into ldap_objclasses (id,name,keytbl,keycol,create_proc,delete_proc,expect_return)
+values (1,'person','persons','id',"insert into persons (name) values ('');\n select last_insert_id();",NULL,0);
-insert into ldap_objclasses (id,name,keytbl,keycol,create_proc,delete_proc)
-values (2,'document','documents','id',NULL,NULL);
+insert into ldap_objclasses (id,name,keytbl,keycol,create_proc,delete_proc,expect_return)
+values (2,'document','documents','id',NULL,NULL,0);
-insert into ldap_objclasses (id,name,keytbl,keycol,create_proc,delete_proc)
-values (3,'organization','institutes','id',NULL,NULL);
+insert into ldap_objclasses (id,name,keytbl,keycol,create_proc,delete_proc,expect_return)
+values (3,'organization','institutes','id',NULL,NULL,0);
-insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc)
-values (1,1,'cn','persons.name','persons',NULL,NULL,NULL,NULL);
+insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return)
+values (1,1,'cn','persons.name','persons',NULL,NULL,NULL,NULL,3,0);
-insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc)
+insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return)
values (2,1,'telephoneNumber','phones.phone','persons,phones',
- 'phones.pers_id=persons.id',NULL,NULL,NULL);
+ 'phones.pers_id=persons.id',NULL,NULL,NULL,3,0);
-insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc)
-values (3,1,'sn','persons.name','persons',NULL,NULL,NULL,NULL);
+insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return)
+values (3,1,'sn','persons.name','persons',NULL,NULL,NULL,NULL,3,0);
-insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc)
-values (4,2,'abstract','documents.abstract','documents',NULL,NULL,NULL,NULL);
+insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return)
+values (4,2,'abstract','documents.abstract','documents',NULL,NULL,NULL,NULL,3,0);
-insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc)
-values (5,2,'documentTitle','documents.title','documents',NULL,NULL,NULL,NULL);
+insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return)
+values (5,2,'documentTitle','documents.title','documents',NULL,NULL,NULL,NULL,3,0);
-insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc)
+insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return)
values (6,2,'documentAuthor','persons.name','persons,documents,authors_docs',
'persons.id=authors_docs.pers_id AND documents.id=authors_docs.doc_id',
- NULL,NULL,NULL);
+ NULL,NULL,NULL,3,0);
-insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc)
-values (7,3,'o','institutes.name','institutes',NULL,NULL,NULL,NULL);
+insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return)
+values (7,3,'o','institutes.name','institutes',NULL,NULL,NULL,NULL,3,0);
-insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc)
+insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return)
values (8,1,'documentDN','ldap_entries.dn','ldap_entries,documents,authors_docs,persons',
'ldap_entries.keyval=documents.id AND ldap_entries.objclass=2 AND authors_docs.doc_id=documents.id AND authors_docs.pers_id=persons.id',
- NULL,NULL,NULL);
+ NULL,NULL,NULL,3,0);
-insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc)
+insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return)
values (9,2,'authorDN','ldap_entries.dn','ldap_entries,documents,authors_docs,persons',
'ldap_entries.keyval=persons.id AND ldap_entries.objclass=1 AND authors_docs.doc_id=documents.id AND authors_docs.pers_id=persons.id',
- NULL,NULL,NULL);
+ NULL,NULL,NULL,3,0);
join_where varchar2(255),
add_proc varchar2(255),
modify_proc varchar2(255),
- delete_proc varchar2(255)
+ delete_proc varchar2(255),
+ param_order NUMBER NOT NULL,
+ expect_return NUMBER NOT NULL
);
keytbl varchar2(64) NOT NULL ,
keycol varchar2(64) NOT NULL ,
create_proc varchar2(255),
- delete_proc varchar2(255)
+ delete_proc varchar2(255),
+ expect_return NUMBER NOT NULL
);
END;
/
-CREATE OR REPLACE PROCEDURE make_author_link (keyval IN NUMBER, author_dn IN varchar2) AS
+CREATE OR REPLACE FUNCTION make_author_link (keyval IN NUMBER, author_dn IN varchar2) RETURN NUMBER AS
per_id NUMBER;
BEGIN
SELECT keyval INTO per_id FROM ldap_entries
WHERE objclass=1 AND dn=author_dn;
IF NOT (per_id IS NULL) THEN
INSERT INTO authors_docs (doc_id,pers_id) VALUES (keyval,per_id);
+ RETURN 1;
END IF;
+RETURN 0;
END;
/
-CREATE OR REPLACE PROCEDURE make_doc_link (keyval IN NUMBER, doc_dn IN varchar2) AS
+CREATE OR REPLACE FUNCTION make_doc_link (keyval IN NUMBER, doc_dn IN varchar2) RETURN NUMBER AS
docid NUMBER;
BEGIN
SELECT keyval INTO docid FROM ldap_entries
WHERE objclass=2 AND dn=doc_dn;
IF NOT (docid IS NULL) THEN
INSERT INTO authors_docs (pers_id,doc_id) VALUES (keyval,docid);
+ RETURN 1;
END IF;
+RETURN 0;
END;
/
-CREATE OR REPLACE PROCEDURE del_doc_link (keyval IN NUMBER, doc_dn IN varchar2) AS
+CREATE OR REPLACE FUNCTION del_doc_link (keyval IN NUMBER, doc_dn IN varchar2) RETURN NUMBER AS
docid NUMBER;
BEGIN
SELECT keyval INTO docid FROM ldap_entries
WHERE objclass=2 AND dn=doc_dn;
IF NOT (docid IS NULL) THEN
DELETE FROM authors_docs WHERE pers_id=keyval AND doc_id=docid;
+ RETURN 1;
END IF;
+RETURN 0;
END;
/
-CREATE PROCEDURE del_author_link (keyval IN NUMBER, author_dn IN varchar2) AS
+CREATE OR REPLACE FUNCTION del_author_link (keyval IN NUMBER, author_dn IN varchar2) RETURN NUMBER AS
per_id NUMBER;
BEGIN
SELECT keyval INTO per_id FROM ldap_entries
IF NOT (per_id IS NULL) THEN
DELETE FROM authors_docs WHERE doc_id=keyval AND pers_id=per_id;
+ RETURN 1;
END IF;
+ RETURN 0;
END;
/
dbname ldap_ora8
dbuser ldap
dbpasswd ldap
-subtree_cond "ldap_entries.dn LIKE CONCAT('%',?)"
+subtree_cond "UPPER(ldap_entries.dn) LIKE CONCAT('%',UPPER(?))"
insentry_query "INSERT INTO ldap_entries (id,dn,objclass,parent,keyval) VALUES (ldap_entry_ids.nextval,?,?,?,?)"
+upper_func UPPER
-insert into ldap_objclasses (id,name,keytbl,keycol,create_proc,delete_proc)
-values (1,'person','persons','id','{call create_person(?)}','{call delete_person(?)}');
+insert into ldap_objclasses (id,name,keytbl,keycol,create_proc,delete_proc,expect_return)
+values (1,'person','persons','id','{call create_person(?)}','{call delete_person(?)}',0);
-insert into ldap_objclasses (id,name,keytbl,keycol,create_proc,delete_proc)
-values (2,'document','documents','id','{call create_document(?)}','{call delete_document(?)}');
+insert into ldap_objclasses (id,name,keytbl,keycol,create_proc,delete_proc,expect_return)
+values (2,'document','documents','id','{call create_document(?)}','{call delete_document(?)}',0);
-insert into ldap_objclasses (id,name,keytbl,keycol,create_proc,delete_proc)
-values (3,'organization','institutes','id','{call create_org(?)}','{call delete_org(?)}');
+insert into ldap_objclasses (id,name,keytbl,keycol,create_proc,delete_proc,expect_return)
+values (3,'organization','institutes','id','{call create_org(?)}','{call delete_org(?)}',0);
-insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc)
+insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return)
values (1,1,'cn','persons.name','persons',NULL,'{call set_person_name(?,?)}',
- NULL,NULL);
+ NULL,NULL,0,0);
-insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc)
+insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return)
values (2,1,'telephoneNumber','phones.phone','persons,phones',
'phones.pers_id=persons.id','{call add_phone(?,?)}',
- NULL,'{call delete_phone(?,?)}');
+ NULL,'{call delete_phone(?,?)}',0,0);
-insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc)
+insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return)
values (3,1,'sn','persons.name','persons',NULL,'{call set_person_name(?,?)}',
- NULL,NULL);
+ NULL,NULL,0,0);
-insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc)
+insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return)
values (4,2,'abstract','documents.abstract','documents',NULL,'{call set_doc_abstract(?,?)}',
- NULL,NULL);
+ NULL,NULL,0,0);
-insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc)
+insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return)
values (5,2,'documentTitle','documents.title','documents',NULL,'{call set_doc_title(?,?)}',
- NULL,NULL);
+ NULL,NULL,0,0);
-insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc)
+insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return)
values (6,2,'documentAuthor','persons.name','persons,documents,authors_docs',
'persons.id=authors_docs.pers_id AND documents.id=authors_docs.doc_id',
- NULL,NULL,NULL);
+ NULL,NULL,NULL,0,0);
-insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc)
+insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return)
values (7,3,'o','institutes.name','institutes',NULL,'{call set_org_name(?,?)}',
- NULL,NULL);
+ NULL,NULL,0,0);
-insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc)
+insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return)
values (8,1,'documentDN','ldap_entries.dn','ldap_entries,documents,authors_docs,persons',
'ldap_entries.keyval=documents.id AND ldap_entries.objclass=2 AND authors_docs.doc_id=documents.id AND authors_docs.pers_id=persons.id',
- '{call make_doc_link(?,?)}',NULL,'{call del_doc_link(?,?)}');
+ '{?=call make_doc_link(?,?)}',NULL,'{?=call del_doc_link(?,?)}',0,3);
-insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc)
+insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return)
values (9,2,'authorDN','ldap_entries.dn','ldap_entries,documents,authors_docs,persons',
'ldap_entries.keyval=persons.id AND ldap_entries.objclass=1 AND authors_docs.doc_id=documents.id AND authors_docs.pers_id=persons.id',
- '{call make_author_link(?,?)}',NULL,'{call del_author_link(?,?)}');
+ '{?=call make_author_link(?,?)}',NULL,'{?=call del_author_link(?,?)}',0,3);
/*
- * Copyright 1999, Dmitry Kovalev (zmit@mail.ru), All rights reserved.
+ * Copyright 1999, Dmitry Kovalev <mit@openldap.org>, 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
{
oc_map=(backsql_oc_map_rec*)ch_calloc(1,sizeof(backsql_oc_map_rec));
oc_map->id=atoi(oc_row.cols[0]);
- oc_map->name=strdup(oc_row.cols[1]);
- oc_map->keytbl=strdup(oc_row.cols[2]);
- oc_map->keycol=strdup(oc_row.cols[3]);
- oc_map->create_proc=(oc_row.is_null[4]<0)?NULL:strdup(oc_row.cols[4]);
- oc_map->delete_proc=(oc_row.is_null[5]<0)?NULL:strdup(oc_row.cols[5]);
+ oc_map->name=ch_strdup(oc_row.cols[1]);
+ oc_map->keytbl=ch_strdup(oc_row.cols[2]);
+ oc_map->keycol=ch_strdup(oc_row.cols[3]);
+ oc_map->create_proc=(oc_row.is_null[4]<0)?NULL:ch_strdup(oc_row.cols[4]);
+ oc_map->delete_proc=(oc_row.is_null[5]<0)?NULL:ch_strdup(oc_row.cols[5]);
+ oc_map->expect_return=atoi(oc_row.cols[6]);
+
oc_map->attrs=NULL;
avl_insert(&si->oc_by_name,oc_map,(AVL_CMP)backsql_cmp_oc_name,backsql_dummy);
avl_insert(&si->oc_by_id,oc_map,(AVL_CMP)backsql_cmp_oc_id,backsql_dummy);
oc_id=oc_map->id;
Debug(LDAP_DEBUG_TRACE,"load_schema_map(): objectclass '%s': keytbl='%s' keycol='%s' ",
- oc_row.cols[1],oc_row.cols[2],oc_row.cols[3]);
- Debug(LDAP_DEBUG_TRACE,"create_proc='%s' delete_proc='%s' ; attributes:\n",oc_row.cols[4],
- oc_row.cols[5],0);
+ oc_map->name,oc_map->keytbl,oc_map->keycol);
+ Debug(LDAP_DEBUG_TRACE,"create_proc='%s' delete_proc='%s' expect_return=%d; attributes:\n",
+ oc_map->create_proc,oc_map->delete_proc,oc_map->expect_return);
if ((rc=SQLExecute(at_sth)) != SQL_SUCCESS)
{
Debug(LDAP_DEBUG_TRACE,"load_schema_map(): error executing at_query: \n",0,0,0);
at_row.cols[4],at_row.cols[5]);
Debug(LDAP_DEBUG_TRACE,"delete_proc='%s'\n",at_row.cols[6],0,0);
at_map=(backsql_at_map_rec*)ch_calloc(1,sizeof(backsql_at_map_rec));
- at_map->name=strdup(at_row.cols[0]);
- at_map->sel_expr=strdup(at_row.cols[1]);
+ at_map->name=ch_strdup(at_row.cols[0]);
+ at_map->sel_expr=ch_strdup(at_row.cols[1]);
tmps=NULL;tmpslen=0;
backsql_merge_from_clause(&tmps,&tmpslen,at_row.cols[2]);
- at_map->from_tbls=strdup(tmps);
+ at_map->from_tbls=ch_strdup(tmps);
ch_free(tmps);
- at_map->join_where=strdup((at_row.is_null[3]<0)?"":at_row.cols[3]);
- at_map->add_proc=(at_row.is_null[4]<0)?NULL:strdup(at_row.cols[4]);
- at_map->modify_proc=(at_row.is_null[5]<0)?NULL:strdup(at_row.cols[5]);
- at_map->delete_proc=(at_row.is_null[6]<0)?NULL:strdup(at_row.cols[6]);
+ at_map->join_where=ch_strdup((at_row.is_null[3]<0)?"":at_row.cols[3]);
+ at_map->add_proc=(at_row.is_null[4]<0)?NULL:ch_strdup(at_row.cols[4]);
+ at_map->modify_proc=(at_row.is_null[5]<0)?NULL:ch_strdup(at_row.cols[5]);
+ at_map->delete_proc=(at_row.is_null[6]<0)?NULL:ch_strdup(at_row.cols[6]);
+ at_map->param_order=atoi(at_row.cols[7]);
+ at_map->expect_return=atoi(at_row.cols[8]);
tmps=NULL;tmpslen=0;
tmps=backsql_strcat(tmps,&tmpslen,"SELECT ",at_map->sel_expr," AS ",at_map->name,
" FROM ",at_map->from_tbls,
" WHERE ",oc_map->keytbl,".",oc_map->keycol,"=?",NULL);
if (at_map->join_where!=NULL && at_map->join_where[0]!='\0')
tmps=backsql_strcat(tmps,&tmpslen," AND ",at_map->join_where,NULL);
- at_map->query=strdup(tmps);
+ at_map->query=ch_strdup(tmps);
ch_free(tmps);
Debug(LDAP_DEBUG_TRACE,"load_schema_map(): preconstructed query '%s'\n",at_map->query,0,0);
avl_insert(&oc_map->attrs,at_map,(AVL_CMP)backsql_cmp_attr,backsql_dummy);
return 0;
}
-#endif /* SLAPD_SQL */
\ No newline at end of file
+#endif /* SLAPD_SQL */
#ifndef __BACKSQL_SCHEMA_MAP_H__
#define __BACKSQL_SCHEMA_MAP_H__
+/*
+ * Copyright 1999, Dmitry Kovalev <mit@openldap.org>, 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.
+ */
+
+
typedef struct
{
char *name;
char *keycol;
char *create_proc;//expected to return keyval of newly created entry
char *delete_proc;//supposed to expect keyval as parameter and delete all the attributes as well
+ int expect_return; //flags whether delete_proc is a function (whether back-sql should bind first parameter as output for return code)
unsigned long id;
Avlnode *attrs;
}backsql_oc_map_rec;
char *modify_proc; //supposed to expect two binded values: entry keyval and old and new values of attr
char *delete_proc; //supposed to expect 2 binded values: entry keyval and attr. value to delete
char *query; //for optimization purposes attribute load query is preconstructed from parts on schemamap load time
+ //following flags are bitmasks (first bit used for add_proc, second - for modify, third - for delete_proc)
+ int param_order; //order of parameters for procedures above; 1 means "data then keyval", 0 means "keyval then data"
+ int expect_return; //flags whether one or more of procedures is a function (whether back-sql should bind first parameter as output for return code)
}backsql_at_map_rec;
+//defines to support bitmasks above
+#define BACKSQL_ADD 1
+#define BACKSQL_DEL 2
+
int backsql_load_schema_map(backsql_info *si,SQLHDBC dbh);
backsql_oc_map_rec* backsql_oc_with_name(backsql_info *si,char* objclass);
backsql_oc_map_rec* backsql_oc_with_id(backsql_info *si,unsigned long id);
/*
- * Copyright 1999, Dmitry Kovalev (zmit@mail.ru), All rights reserved.
+ * Copyright 1999, Dmitry Kovalev <mit@openldap.org>, 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
}
Debug(LDAP_DEBUG_TRACE,"==>backsql_attrlist_add(): adding '%s' to list\n",at_name,0,0);
bsi->attrs=(char**)ch_realloc(bsi->attrs,(n_attrs+2)*sizeof(char*));
- bsi->attrs[n_attrs]=strdup(at_name);
+ bsi->attrs[n_attrs]=ch_strdup(at_name);
bsi->attrs[n_attrs+1]=NULL;
return 1;
}
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)
+ SQLHDBC dbh,BackendDB *be,Connection *conn,Operation *op,char **attrs)
{
char **p;
bsi->base_dn=nbase;
{
res=backsql_process_filter(bsi,f);
- if (res==-1)
- bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len," 1=0 ",NULL);
-
f=f->f_next;
if (f==NULL)
break;
backsql_at_map_rec *at=backsql_at_with_name(bsi->oc,f->f_sub_type);
- bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,"(",at->sel_expr,
+ bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,"(",NULL);
+
+ if (bsi->bi->upper_func)
+ {
+ bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,
+ bsi->bi->upper_func,"(",at->sel_expr,")",
+ " LIKE '",NULL);
+ }
+ else
+ {
+ bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,at->sel_expr,
" LIKE '",NULL);
+ }
if (f->f_sub_initial!=NULL)
- bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,f->f_sub_initial,NULL);
+ {
+ bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,f->f_sub_initial->bv_val,NULL);
+ }
bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,"%",NULL);
if (f->f_sub_any!=NULL)
for(i=0;f->f_sub_any[i]!=NULL;i++)
- bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,f->f_sub_any[i],"%",NULL);
+ {
+ //Debug(LDAP_DEBUG_TRACE,"==>backsql_process_sub_filter(): sub_any='%s'\n",f->f_sub_any[i]->bv_val,0,0);
+ bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,f->f_sub_any[i]->bv_val,"%",NULL);
+ }
if (f->f_sub_final!=NULL)
- bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,f->f_sub_final,NULL);
+ bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,f->f_sub_final->bv_val,NULL);
bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,"')",NULL);
{
Debug(LDAP_DEBUG_TRACE,"backsql_process_filter(): attribute '%s' is not defined for objectclass '%s'\n",
at_name,bsi->oc->name,0);
+ bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len," 1=0 ",NULL);
return -1;
}
switch(f->f_choice)
{
case LDAP_FILTER_EQUALITY:
- bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,"(",at->sel_expr,"='",
- f->f_avvalue.bv_val,"')",NULL);
+ //maybe we should check type of at->sel_expr here somehow,
+ //to know whether upper_func is applicable, but for now
+ //upper_func stuff is made for Oracle, where UPPER is
+ //safely applicable to NUMBER etc.
+ if (bsi->bi->upper_func)
+ bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,"(",
+ bsi->bi->upper_func,"(",at->sel_expr,")='",
+ f->f_avvalue.bv_val,"')",NULL);
+ else
+ bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,"(",at->sel_expr,"='",
+ f->f_avvalue.bv_val,"')",NULL);
break;
case LDAP_FILTER_GE:
bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,"(",at->sel_expr,">=",
switch(bsi->scope)
{
case LDAP_SCOPE_BASE:
- bsi->join_where=backsql_strcat(bsi->join_where,&bsi->jwhere_len,
+ if (bsi->bi->upper_func)
+ {
+ bsi->join_where=backsql_strcat(bsi->join_where,&bsi->jwhere_len,
+ bsi->bi->upper_func,"(","ldap_entries.dn)=(?)",NULL);
+ }
+ else
+ {
+ bsi->join_where=backsql_strcat(bsi->join_where,&bsi->jwhere_len,
"ldap_entries.dn=?",NULL);
+ }
break;
case LDAP_SCOPE_ONELEVEL:
bsi->join_where=backsql_strcat(bsi->join_where,&bsi->jwhere_len,
}
break;
case LDAP_SCOPE_ONELEVEL:
- res=backsql_dn2id(&base_id,bsi->dbh,bsi->base_dn);
+ res=backsql_dn2id(bsi->bi,&base_id,bsi->dbh,bsi->base_dn);
if (res==NULL)
{
Debug(LDAP_DEBUG_TRACE,"backsql_oc_get_candidates(): could not retrieve base_dn id - no such entry\n",0,0,0);
}
*/
- Debug(LDAP_DEBUG_TRACE,"backsql_oc_get_candidates(): adding entry id=%s, keyval=%s dn='%s'\n",
- row.cols[0],row.cols[1],row.cols[3]);
c_id=(backsql_entryID*)ch_calloc(1,sizeof(backsql_entryID));
c_id->id=atoi(row.cols[0]);
c_id->keyval=atoi(row.cols[1]);
c_id->oc_id=bsi->oc->id;
- c_id->dn=strdup(row.cols[3]);
+ c_id->dn=ch_strdup(row.cols[3]);
c_id->next=bsi->id_list;
bsi->id_list=c_id;
+ Debug(LDAP_DEBUG_TRACE,"backsql_oc_get_candidates(): added entry id=%d, keyval=%d dn='%s'\n",
+ c_id->id,c_id->keyval,row.cols[3]);
}
backsql_FreeRow(&row);
SQLFreeStmt(sth,SQL_DROP);
return 1;
}
-
-int backsql_search(Backend *be,Connection *conn,Operation *op,
- char *base, char *nbase, int scope,int deref,int slimit,int tlimit,
- Filter *filter, char *filterstr,char **attrs,int attrsonly)
+int backsql_search(BackendDB *be,Connection *conn,Operation *op,
+ const char *base, const char *nbase, int scope,int deref,int slimit,int tlimit,
+ Filter *filter, const char *filterstr,char **attrs,int attrsonly)
{
backsql_info *bi=(backsql_info*)be->be_private;
SQLHDBC dbh;
backsql_srch_info srch_info;
backsql_entryID *eid=NULL;
- base=dn_validate(base);
Debug(LDAP_DEBUG_TRACE,"==>backsql_search(): base='%s', filter='%s', scope=%d,",
- base,filterstr,scope);
+ nbase,filterstr,scope);
Debug(LDAP_DEBUG_TRACE," deref=%d, attrsonly=%d, attributes to load: %s\n",
deref,attrsonly,attrs==NULL?"all":"custom list");
dbh=backsql_get_db_conn(be,conn);
be->be_sizelimit : slimit;
}
- //backsql_init_search(&srch_info,bi,nbase/*!!!!!!!!*/,scope,slimit,tlimit,stoptime,filter,dbh,
-// be,conn,op,attrs);
- backsql_init_search(&srch_info,bi,base/*don't know so far how to make Oracle do CIS search on VARCHAR2*/,
- scope,slimit,tlimit,stoptime,filter,dbh,
- be,conn,op,attrs);
+ backsql_init_search(&srch_info,bi,(char*)nbase,scope,slimit,tlimit,stoptime,filter,dbh,
+ be,conn,op,attrs);
//for each objectclass we try to construct query which gets IDs
//of entries matching LDAP query filter and scope (or at least candidates),
for(eid=srch_info.id_list;eid!=NULL;eid=backsql_free_entryID(eid));
- //free bsi->attrs!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ charray_free(srch_info.attrs);
if (nentries>0)
send_search_result( conn, op,
return 0;
}
-#endif /* SLAPD_SQL */
\ No newline at end of file
+#endif /* SLAPD_SQL */
#define __BACKSQL_SQL_TYPES_H__
/*
- * Copyright 1999, Dmitry Kovalev (zmit@mail.ru), All rights reserved.
+ * Copyright 1999, Dmitry Kovalev <mit@openldap.org>, 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
/*
- * Copyright 1999, Dmitry Kovalev (zmit@mail.ru), All rights reserved.
+ * Copyright 1999, Dmitry Kovalev <mit@openldap.org>, 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
{
rc=SQLDescribeCol(sth,(SQLSMALLINT)i,&colname[0],(SQLUINTEGER)sizeof(colname)-1,&name_len,&col_type,
(UDWORD*) &col_prec,&col_scale,&col_null);
- row->col_names[i-1]=strdup(colname);
+ row->col_names[i-1]=ch_strdup(colname);
//Debug(LDAP_DEBUG_TRACE,"backsql_BindRowAsStrings: col_name=%s, col_prec[%d]=%d\n",colname,(int)i,(int)col_prec);
if (col_type == SQL_LONGVARCHAR || col_type== SQL_LONGVARBINARY)
{
return dbc->dbh;
}
-#endif /* SLAPD_SQL */
\ No newline at end of file
+#endif /* SLAPD_SQL */
#define __BACKSQL_SQL_WRAP_H__
/*
- * Copyright 1999, Dmitry Kovalev (zmit@mail.ru), All rights reserved.
+ * Copyright 1999, Dmitry Kovalev <mit@openldap.org>, 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
/*
- * Copyright 1999, Dmitry Kovalev (zmit@mail.ru), All rights reserved.
+ * Copyright 1999, Dmitry Kovalev <mit@openldap.org>, 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
#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_oc_query[]="SELECT id,name,keytbl,keycol,create_proc,delete_proc,expect_return FROM ldap_objclasses";
+char backsql_def_at_query[]="SELECT name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return 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_id_query[]="SELECT id,keyval,objclass FROM ldap_entries WHERE ";
char* backsql_strcat(char* dest,int *buflen, ...)
{
//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_type=ch_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;
//Debug(LDAP_DEBUG_TRACE,"==>backsql_merge_from_clause(): dest_from='%s',src_from='%s'\n",
// dest_from,src_from,0);
- srcc=strdup(src_from);
+ srcc=ch_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)
return 1;
}
-#endif /* SLAPD_SQL */
\ No newline at end of file
+#endif /* SLAPD_SQL */
#ifndef __BACKSQL_UTIL_H__
#define __BACKSQL_UTIL_H__
+/*
+ * Copyright 1999, Dmitry Kovalev <mit@openldap.org>, 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 "entry-id.h"
#include "schema-map.h"
extern char backsql_def_oc_query[],backsql_def_at_query[],
backsql_def_delentry_query[],backsql_def_insentry_query[],
- backsql_def_subtree_cond[];
+ backsql_def_subtree_cond[],backsql_id_query[];
int backsql_merge_from_clause(char **dest_from,int *dest_len,char *src_from);