Commit b8af4a67 authored by Dmitry Kovalev's avatar Dmitry Kovalev
Browse files

Summary of changes:

- filter -> SQL translation bugfixes
- several memory leaks fixups
- improved configurability:
    - allows definition of  uppercasing function to support CIS matching on databases that do
    case sensitive compares (this fixes up Oracle issues, example updated)
    - allows more flexibility in stored procedures interface (different parameter order, optional return
      codes - see samples, and comments in backsql.h)
- synchronize function interfaces to recent changes in prototypes ("const" clauses etc.) made for all backends
  (those changes led to compile-time errors)
parent 60981bdc
......@@ -2,7 +2,7 @@
#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
......@@ -27,6 +27,8 @@ typedef struct
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
......@@ -17,8 +17,8 @@
#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
......@@ -27,7 +27,7 @@ int backsql_bind(Backend *be,Connection *conn,Operation *op,
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
......@@ -38,7 +38,7 @@ int backsql_db_config(BackendDB *be,const char *fname,int lineno,int argc,char *
}
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);
......@@ -53,7 +53,7 @@ int backsql_db_config(BackendDB *be,const char *fname,int lineno,int argc,char *
}
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);
......@@ -68,7 +68,7 @@ int backsql_db_config(BackendDB *be,const char *fname,int lineno,int argc,char *
}
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);
......@@ -83,7 +83,7 @@ int backsql_db_config(BackendDB *be,const char *fname,int lineno,int argc,char *
}
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);
......@@ -98,7 +98,7 @@ int backsql_db_config(BackendDB *be,const char *fname,int lineno,int argc,char *
}
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);
......@@ -113,7 +113,7 @@ int backsql_db_config(BackendDB *be,const char *fname,int lineno,int argc,char *
}
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);
......@@ -128,7 +128,7 @@ int backsql_db_config(BackendDB *be,const char *fname,int lineno,int argc,char *
}
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);
......@@ -143,12 +143,27 @@ int backsql_db_config(BackendDB *be,const char *fname,int lineno,int argc,char *
}
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)
......@@ -158,7 +173,7 @@ int backsql_db_config(BackendDB *be,const char *fname,int lineno,int argc,char *
}
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);
......@@ -168,4 +183,5 @@ int backsql_db_config(BackendDB *be,const char *fname,int lineno,int argc,char *
fname,lineno,argv[0]);
return 0;
}
#endif /* SLAPD_SQL */
\ No newline at end of file
#endif /* SLAPD_SQL */
......@@ -25,12 +25,6 @@
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
......@@ -30,16 +30,15 @@ backsql_entryID* backsql_free_entryID(backsql_entryID* id)
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);
......@@ -66,7 +65,7 @@ backsql_entryID* backsql_dn2id(backsql_entryID *id,SQLHDBC dbh,char *dn)
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
......@@ -147,7 +146,7 @@ Entry* backsql_id2entry(backsql_srch_info *bsi,Entry* e,backsql_entryID* eid)
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)
{
......@@ -179,4 +178,4 @@ Entry* backsql_id2entry(backsql_srch_info *bsi,Entry* e,backsql_entryID* eid)
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;
......@@ -10,7 +20,7 @@ typedef struct __backsql_entryID
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
......@@ -2,6 +2,16 @@
#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
......@@ -116,6 +116,8 @@ int backsql_db_destroy(BackendDB *bd)
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);
......@@ -131,6 +133,7 @@ int backsql_db_open (BackendDB *bd)
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)
......@@ -147,32 +150,42 @@ int backsql_db_open (BackendDB *bd)
{
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)
......@@ -181,6 +194,11 @@ int backsql_db_open (BackendDB *bd)
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;
}
......@@ -192,4 +210,4 @@ int backsql_db_close(BackendDB *bd)
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
......@@ -22,7 +22,7 @@
#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;
......@@ -34,9 +34,10 @@ int backsql_modify(BackendDB *be,Connection *conn,Operation *op,
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)
{
......@@ -44,7 +45,7 @@ int backsql_modify(BackendDB *be,Connection *conn,Operation *op,
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);
......@@ -69,16 +70,14 @@ int backsql_modify(BackendDB *be,Connection *conn,Operation *op,
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;
......@@ -89,27 +88,17 @@ int backsql_modify(BackendDB *be,Connection *conn,Operation *op,
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;
......@@ -117,7 +106,7 @@ del_all:
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;
......@@ -128,7 +117,18 @@ del_all:
{
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)
......@@ -156,8 +156,18 @@ del_all:
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)
......@@ -181,8 +191,18 @@ del_all:
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)
......@@ -203,7 +223,7 @@ del_all:
}
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;
......@@ -223,6 +243,8 @@ int backsql_add(BackendDB *be,Connection *conn,Operation *op,Entry *e)
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)
......@@ -262,7 +284,6 @@ int backsql_add(BackendDB *be,Connection *conn,Operation *op,Entry *e)
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);
......@@ -290,13 +311,20 @@ int backsql_add(BackendDB *be,Connection *conn,Operation *op,Entry *e)
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)
......@@ -308,7 +336,7 @@ int backsql_add(BackendDB *be,Connection *conn,Operation *op,Entry *e)
}
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",
......@@ -337,7 +365,7 @@ int backsql_add(BackendDB *be,Connection *conn,Operation *op,Entry *e)
}
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;
......@@ -345,9 +373,9 @@ int backsql_delete(BackendDB *be,Connection *conn,Operation *op,
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)