more back-sql files + rdbms_dependent samples

This commit is contained in:
Dmitry Kovalev 2000-03-16 19:34:46 +00:00
parent 91f292bc00
commit 4e703c5261
25 changed files with 2179 additions and 0 deletions

View file

@ -0,0 +1,36 @@
/*
* 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 <stdio.h>
#include <sys/types.h>
#include "slap.h"
#include "back-sql.h"
#include "sql-wrap.h"
int backsql_dummy()
{
return 0;
}
int backsql_compare(BackendDB *be,Connection *conn,Operation *op,
char *dn,char *ndn,Ava *ava)
{
Debug(LDAP_DEBUG_TRACE,"==>backsql_compare()\n",0,0,0);
return 0;
}
int backsql_abandon( BackendDB *be,
Connection *conn, Operation *op, int msgid )
{
Debug(LDAP_DEBUG_TRACE,"==>backsql_abandon()\n",0,0,0);
Debug(LDAP_DEBUG_TRACE,"<==backsql_abandon()\n",0,0,0);
return 0;
}

View file

@ -0,0 +1,76 @@
CREATE TABLE ldap_attrs (
id int IDENTITY (1, 1) NOT NULL ,
oc_id int NOT NULL ,
name varchar (255) NOT NULL ,
sel_expr varchar (255) NOT NULL ,
from_tbls varchar (255) NOT NULL ,
join_where varchar (255) NULL ,
add_proc varchar (255) NULL ,
modify_proc varchar (255) NULL ,
delete_proc varchar (255) NULL
)
GO
CREATE TABLE ldap_entries (
id int IDENTITY (1, 1) NOT NULL ,
dn varchar (255) NOT NULL ,
objclass int NOT NULL ,
parent int NOT NULL ,
keyval int NOT NULL
)
GO
CREATE TABLE ldap_objclasses (
id int IDENTITY (1, 1) NOT NULL ,
name varchar (64) NOT NULL ,
keytbl varchar (64) NOT NULL ,
keycol varchar (64) NOT NULL ,
create_proc varchar (255) NULL ,
delete_proc varchar (255) NULL
)
GO
ALTER TABLE ldap_attrs WITH NOCHECK ADD
CONSTRAINT PK_ldap_attrs PRIMARY KEY
(
id
)
GO
ALTER TABLE ldap_entries WITH NOCHECK ADD
CONSTRAINT PK_ldap_entries PRIMARY KEY
(
id
)
GO
ALTER TABLE ldap_entries WITH NOCHECK ADD
CONSTRAINT UNQ1_ldap_entries UNIQUE
(
objclass,
keyval
)
GO
ALTER TABLE ldap_entries WITH NOCHECK ADD
CONSTRAINT UNQ2_ldap_entries UNIQUE
(
dn
)
GO
ALTER TABLE ldap_objclasses WITH NOCHECK ADD
CONSTRAINT PK_ldap_objclasses PRIMARY KEY
(
id
)
GO
ALTER TABLE ldap_objclasses WITH NOCHECK ADD
CONSTRAINT UNQ_ldap_objclasses UNIQUE
(
name
)
GO

View file

@ -0,0 +1,160 @@
CREATE TABLE authors_docs (
pers_id int NOT NULL ,
doc_id int NOT NULL
)
GO
CREATE TABLE documents (
id int IDENTITY (1, 1) NOT NULL ,
abstract varchar (255) NULL ,
title varchar (255) NULL ,
body binary (255) NULL
)
GO
CREATE TABLE institutes (
id int IDENTITY (1, 1) NOT NULL ,
name varchar (255) NOT NULL
)
GO
CREATE TABLE persons (
id int IDENTITY (1, 1) NOT NULL ,
name varchar (255) NULL
)
GO
CREATE TABLE phones (
id int IDENTITY (1, 1) NOT NULL ,
phone varchar (255) NOT NULL ,
pers_id int NOT NULL
)
GO
ALTER TABLE authors_docs WITH NOCHECK ADD
CONSTRAINT PK_authors_docs PRIMARY KEY
(
pers_id,
doc_id
)
GO
ALTER TABLE documents WITH NOCHECK ADD
CONSTRAINT PK_documents PRIMARY KEY
(
id
)
GO
ALTER TABLE institutes WITH NOCHECK ADD
CONSTRAINT PK_institutes PRIMARY KEY
(
id
)
GO
ALTER TABLE persons WITH NOCHECK ADD
CONSTRAINT PK_persons PRIMARY KEY
(
id
)
GO
ALTER TABLE phones WITH NOCHECK ADD
CONSTRAINT PK_phones PRIMARY KEY
(
id
)
GO
SET QUOTED_IDENTIFIER OFF SET ANSI_NULLS ON
GO
CREATE PROCEDURE add_phone @pers_id int, @phone varchar(255) AS
INSERT INTO ldap.phones (pers_id,phone) VALUES (@pers_id,@phone)
GO
CREATE PROCEDURE create_person @@keyval int OUTPUT AS
INSERT INTO ldap.persons (name) VALUES ('');
set @@keyval=(SELECT MAX(id) FROM ldap.persons)
GO
CREATE PROCEDURE delete_person @keyval int AS
DELETE FROM ldap.phones WHERE pers_id=@keyval;
DELETE FROM ldap.authors_docs WHERE pers_id=@keyval;
DELETE FROM ldap.persons WHERE id=@keyval;
GO
CREATE PROCEDURE create_org @@keyval int OUTPUT AS
INSERT INTO ldap.institutes (name) VALUES ('');
set @@keyval=(SELECT MAX(id) FROM ldap.institutes)
GO
CREATE PROCEDURE create_document @@keyval int OUTPUT AS
INSERT INTO ldap.documents (title) VALUES ('');
set @@keyval=(SELECT MAX(id) FROM ldap.documents)
GO
CREATE PROCEDURE delete_org @keyval int AS
DELETE FROM ldap.institutes WHERE id=@keyval;
GO
CREATE PROCEDURE delete_document @keyval int AS
DELETE FROM ldap.authors_docs WHERE doc_id=@keyval;
DELETE FROM ldap.documents WHERE id=@keyval;
GO
CREATE PROCEDURE delete_phone @keyval int,@phone varchar(64) AS
DELETE FROM ldap.phones WHERE pers_id=@keyval AND phone=@phone;
GO
CREATE PROCEDURE set_person_name @keyval int, @new_name varchar(255) AS
UPDATE ldap.persons SET name=@new_name WHERE id=@keyval;
GO
CREATE PROCEDURE set_org_name @keyval int, @new_name varchar(255) AS
UPDATE ldap.institutes SET name=@new_name WHERE id=@keyval;
GO
CREATE PROCEDURE set_doc_title @keyval int, @new_title varchar(255) AS
UPDATE ldap.documents SET title=@new_title WHERE id=@keyval;
GO
CREATE PROCEDURE set_doc_abstract @keyval int, @new_abstract varchar(255) AS
UPDATE ldap.documents SET abstract=@new_abstract WHERE id=@keyval;
GO
CREATE PROCEDURE make_author_link @keyval int, @author_dn varchar(255) AS
DECLARE @per_id int;
SET @per_id=(SELECT keyval FROM ldap.ldap_entries
WHERE objclass=1 AND dn=@author_dn);
IF NOT (@per_id IS NULL)
INSERT INTO ldap.authors_docs (doc_id,pers_id) VALUES (@keyval,@per_id);
GO
CREATE PROCEDURE make_doc_link @keyval int, @doc_dn varchar(255) AS
DECLARE @doc_id int;
SET @doc_id=(SELECT keyval FROM ldap.ldap_entries
WHERE objclass=2 AND dn=@doc_dn);
IF NOT (@doc_id IS NULL)
INSERT INTO ldap.authors_docs (pers_id,doc_id) VALUES (@keyval,@doc_id);
GO
CREATE PROCEDURE del_doc_link @keyval int, @doc_dn varchar(255) AS
DECLARE @doc_id int;
SET @doc_id=(SELECT keyval FROM ldap.ldap_entries
WHERE objclass=2 AND dn=@doc_dn);
IF NOT (@doc_id IS NULL)
DELETE FROM ldap.authors_docs WHERE pers_id=@keyval AND doc_id=@doc_id;
GO
CREATE PROCEDURE del_author_link @keyval int, @author_dn varchar(255) AS
DECLARE @per_id int;
SET @per_id=(SELECT keyval FROM ldap.ldap_entries
WHERE objclass=1 AND dn=@author_dn);
IF NOT (@per_id IS NULL)
DELETE FROM ldap.authors_docs WHERE doc_id=@keyval AND pers_id=@per_id;
GO

View file

@ -0,0 +1,13 @@
if exists (select * from sysobjects where id = object_id(N'ldap_attrs') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table ldap_attrs
GO
if exists (select * from sysobjects where id = object_id(N'ldap_entries') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table ldap_entries
GO
if exists (select * from sysobjects where id = object_id(N'ldap_objclasses') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table ldap_objclasses
GO

View file

@ -0,0 +1,39 @@
drop procedure create_person
drop procedure set_person_name
drop procedure delete_phone
drop procedure add_phone
drop procedure make_doc_link
drop procedure del_doc_link
drop procedure delete_person
drop procedure create_org
drop procedure set_org_name
drop procedure delete_org
drop procedure create_document
drop procedure set_doc_title
drop procedure set_doc_abstract
drop procedure make_author_link
drop procedure del_author_link
drop procedure delete_document
if exists (select * from sysobjects where id = object_id(N'authors_docs') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table authors_docs
GO
if exists (select * from sysobjects where id = object_id(N'documents') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table documents
GO
if exists (select * from sysobjects where id = object_id(N'institutes') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table institutes
GO
if exists (select * from sysobjects where id = object_id(N'persons') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table persons
GO
if exists (select * from sysobjects where id = object_id(N'phones') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table phones
GO

View file

@ -0,0 +1,39 @@
# $OpenLDAP$
#
# See slapd.conf(5) for details on configuration options.
# This file should NOT be world readable.
#
include ./slapd.at.conf
include ./slapd.oc.conf
# Define global ACLs to disable default read access.
# Do not enable referrals until AFTER you have a working directory
# service AND an understanding of referrals.
#referral ldap://root.openldap.org
pidfile ./slapd.pid
argsfile ./slapd.args
#######################################################################
# ldbm database definitions
#######################################################################
#database ldbm
#suffix "dc=your-domain, dc=com"
#suffix "o=Your Organization Name, c=US"
#directory /usr/tmp
#rootdn "cn=root, dc=your-domain, dc=com"
#rootdn "cn=root, o=Your Organization Name, c=US"
#rootpw secret
# cleartext passwords, especially for the rootdn, should
# be avoid. See slapd.conf(5) for details.
database sql
suffix "o=sql,c=RU"
rootdn "cn=root,o=sql,c=RU"
rootpw secret
dbname ldap_mssql
dbuser ldap
dbpasswd ldap
subtree_cond "ldap_entries.dn LIKE '%'+?"

View file

@ -0,0 +1,45 @@
set IDENTITY_INSERT institutes ON
insert into institutes (id,name) values (1,'sql')
set IDENTITY_INSERT institutes OFF
set IDENTITY_INSERT persons ON
insert into persons (id,name) values (1,'Mitya Kovalev')
insert into persons (id,name) values (2,'Torvlobnor Puzdoy')
insert into persons (id,name) values (3,'Akakiy Zinberstein')
set IDENTITY_INSERT persons OFF
set IDENTITY_INSERT phones ON
insert into phones (id,phone,pers_id) values (1,'332-2334',1)
insert into phones (id,phone,pers_id) values (2,'222-3234',1)
insert into phones (id,phone,pers_id) values (3,'545-4563',2)
set IDENTITY_INSERT phones OFF
set IDENTITY_INSERT documents ON
insert into documents (id,abstract,title) values (1,'abstract1','book1')
insert into documents (id,abstract,title) values (2,'abstract2','book2')
set IDENTITY_INSERT documents OFF
insert into authors_docs (pers_id,doc_id) values (1,1)
insert into authors_docs (pers_id,doc_id) values (1,2)
insert into authors_docs (pers_id,doc_id) values (2,1)
SET IDENTITY_INSERT ldap_entries ON
insert into ldap_entries (id,dn,objclass,parent,keyval)
values (1,'o=sql,c=RU',3,0,1)
insert into ldap_entries (id,dn,objclass,parent,keyval)
values (2,'cn=Mitya Kovalev,o=sql,c=RU',1,1,1)
insert into ldap_entries (id,dn,objclass,parent,keyval)
values (3,'cn=Torvlobnor Puzdoy,o=sql,c=RU',1,1,2)
insert into ldap_entries (id,dn,objclass,parent,keyval)
values (4,'cn=Akakiy Zinberstein,o=sql,c=RU',1,1,3)
insert into ldap_entries (id,dn,objclass,parent,keyval)
values (5,'documentTitle=book1,o=sql,c=RU',2,1,1)
insert into ldap_entries (id,dn,objclass,parent,keyval)
values (6,'documentTitle=book2,o=sql,c=RU',2,1,2)
SET IDENTITY_INSERT ldap_entries OFF

View file

@ -0,0 +1,56 @@
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)
values (2,'document','documents','id','{call create_document(?)}','{call delete_document(?)}')
insert into ldap_objclasses (id,name,keytbl,keycol,create_proc,delete_proc)
values (3,'organization','institutes','id','{call create_org(?)}','{call delete_org(?)}')
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)
values (1,1,'cn','persons.name','persons',NULL,'{call set_person_name(?,?)}',
NULL,NULL)
insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc)
values (2,1,'telephoneNumber','phones.phone','persons,phones',
'phones.pers_id=persons.id','{call add_phone(?,?)}',
NULL,'{call delete_phone(?,?)}')
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,'{call set_person_name(?,?)}',
NULL,NULL)
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,'{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)
values (5,2,'documentTitle','documents.title','documents',NULL,'{call set_doc_title(?,?)}',
NULL,NULL)
insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc)
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)
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,'{call set_org_name(?,?)}',
NULL,NULL)
insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc)
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(?,?)}')
insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc)
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(?,?)}')
SET IDENTITY_INSERT ldap_attrs OFF

View file

@ -0,0 +1,50 @@
CREATE TABLE ldap_attrs (
id int NOT NULL PRIMARY KEY AUTO_INCREMENT,
oc_id int NOT NULL,
name varchar(255) NOT NULL,
sel_expr varchar(255) NOT NULL,
from_tbls varchar(255) NOT NULL,
join_where varchar(255),
add_proc varchar(255),
modify_proc varchar(255),
delete_proc varchar(255)
);
CREATE TABLE ldap_entries (
id int NOT NULL PRIMARY KEY AUTO_INCREMENT,
dn varchar(255) NOT NULL ,
objclass int NOT NULL ,
parent int NOT NULL ,
keyval int NOT NULL
);
CREATE TABLE ldap_objclasses (
id int NOT NULL PRIMARY KEY AUTO_INCREMENT,
name varchar(64) NOT NULL ,
keytbl varchar(64) NOT NULL ,
keycol varchar(64) NOT NULL ,
create_proc varchar(255),
delete_proc varchar(255)
);
ALTER TABLE ldap_entries ADD
CONSTRAINT UNQ1_ldap_entries UNIQUE
(
objclass,
keyval
);
ALTER TABLE ldap_entries ADD
CONSTRAINT UNQ2_ldap_entries UNIQUE
(
dn
);
ALTER TABLE ldap_objclasses ADD
CONSTRAINT UNQ_ldap_objclasses UNIQUE
(
name
);

View file

@ -0,0 +1,61 @@
CREATE TABLE persons (
id int NOT NULL,
name varchar(255) NOT NULL
);
CREATE TABLE institutes (
id int NOT NULL,
name varchar(255)
);
CREATE TABLE documents (
id int NOT NULL,
title varchar(255) NOT NULL,
abstract varchar(255)
);
CREATE TABLE authors_docs (
pers_id int NOT NULL,
doc_id int NOT NULL
);
CREATE TABLE phones (
id int NOT NULL ,
phone varchar(255) NOT NULL ,
pers_id int NOT NULL
);
ALTER TABLE authors_docs ADD
CONSTRAINT PK_authors_docs PRIMARY KEY
(
pers_id,
doc_id
);
ALTER TABLE documents ADD
CONSTRAINT PK_documents PRIMARY KEY
(
id
);
ALTER TABLE institutes ADD
CONSTRAINT PK_institutes PRIMARY KEY
(
id
);
ALTER TABLE persons ADD
CONSTRAINT PK_persons PRIMARY KEY
(
id
);
ALTER TABLE phones ADD
CONSTRAINT PK_phones PRIMARY KEY
(
id
);

View file

@ -0,0 +1,5 @@
DROP TABLE IF EXISTS ldap_attrs;
DROP TABLE IF EXISTS ldap_entries;
DROP TABLE IF EXISTS ldap_objclasses;

View file

@ -0,0 +1,5 @@
DROP TABLE IF EXISTS persons;
DROP TABLE IF EXISTS institutes;
DROP TABLE IF EXISTS documents;
DROP TABLE IF EXISTS authors_docs;
DROP TABLE IF EXISTS phones;

View file

@ -0,0 +1,30 @@
# $OpenLDAP$
#
# See slapd.conf(5) for details on configuration options.
# This file should NOT be world readable.
#
include /usr/local/etc/openldap/slapd.at.conf
include /usr/local/etc/openldap/slapd.oc.conf
# Define global ACLs to disable default read access.
# Do not enable referrals until AFTER you have a working directory
# service AND an understanding of referrals.
#referral ldap://root.openldap.org
pidfile /usr/local/var/slapd.pid
argsfile /usr/local/var/slapd.args
#######################################################################
# ldbm database definitions
#######################################################################
database sql
suffix "o=sql,c=RU"
rootdn "cn=root,o=sql,c=RU"
rootpw secret
dbname ldap_mysql
dbuser root
dbpasswd
subtree_cond "ldap_entries.dn LIKE CONCAT('%',?)"
insentry_query "INSERT INTO ldap_entries (dn,objclass,parent,keyval) VALUES (?,?,?,?)"

View file

@ -0,0 +1,34 @@
insert into institutes (id,name) values (1,'sql');
insert into persons (id,name) values (1,'Mitya Kovalev');
insert into persons (id,name) values (2,'Torvlobnor Puzdoy');
insert into persons (id,name) values (3,'Akakiy Zinberstein');
insert into phones (id,phone,pers_id) values (1,'332-2334',1);
insert into phones (id,phone,pers_id) values (2,'222-3234',1);
insert into phones (id,phone,pers_id) values (3,'545-4563',2);
insert into documents (id,abstract,title) values (1,'abstract1','book1');
insert into documents (id,abstract,title) values (2,'abstract2','book2');
insert into authors_docs (pers_id,doc_id) values (1,1);
insert into authors_docs (pers_id,doc_id) values (1,2);
insert into authors_docs (pers_id,doc_id) values (2,1);
insert into ldap_entries (id,dn,objclass,parent,keyval)
values (1,'o=sql,c=RU',3,0,1);
insert into ldap_entries (id,dn,objclass,parent,keyval)
values (2,'cn=Mitya Kovalev,o=sql,c=RU',1,1,1);
insert into ldap_entries (id,dn,objclass,parent,keyval)
values (3,'cn=Torvlobnor Puzdoy,o=sql,c=RU',1,1,2);
insert into ldap_entries (id,dn,objclass,parent,keyval)
values (4,'cn=Akakiy Zinberstein,o=sql,c=RU',1,1,3);
insert into ldap_entries (id,dn,objclass,parent,keyval)
values (5,'documentTitle=book1,o=sql,c=RU',2,1,1);
insert into ldap_entries (id,dn,objclass,parent,keyval)
values (6,'documentTitle=book2,o=sql,c=RU',2,1,2);

View file

@ -0,0 +1,43 @@
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)
values (2,'document','documents','id',NULL,NULL);
insert into ldap_objclasses (id,name,keytbl,keycol,create_proc,delete_proc)
values (3,'organization','institutes','id',NULL,NULL);
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)
values (2,1,'telephoneNumber','phones.phone','persons,phones',
'phones.pers_id=persons.id',NULL,NULL,NULL);
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)
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)
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)
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);
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)
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);
insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc)
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);

View file

@ -0,0 +1,76 @@
CREATE TABLE ldap_attrs (
id NUMBER NOT NULL,
oc_id NUMBER NOT NULL,
name varchar2(255) NOT NULL,
sel_expr varchar2(255) NOT NULL,
from_tbls varchar2(255) NOT NULL,
join_where varchar2(255),
add_proc varchar2(255),
modify_proc varchar2(255),
delete_proc varchar2(255)
);
CREATE TABLE ldap_entries (
id NUMBER NOT NULL ,
dn varchar2(255) NOT NULL ,
objclass NUMBER NOT NULL ,
parent NUMBER NOT NULL ,
keyval NUMBER NOT NULL
);
CREATE TABLE ldap_objclasses (
id NUMBER NOT NULL ,
name varchar2(64) NOT NULL ,
keytbl varchar2(64) NOT NULL ,
keycol varchar2(64) NOT NULL ,
create_proc varchar2(255),
delete_proc varchar2(255)
);
ALTER TABLE ldap_attrs ADD
CONSTRAINT PK_ldap_attrs PRIMARY KEY
(
id
);
ALTER TABLE ldap_entries ADD
CONSTRAINT PK_ldap_entries PRIMARY KEY
(
id
);
ALTER TABLE ldap_objclasses ADD
CONSTRAINT PK_ldap_objclasses PRIMARY KEY
(
id
);
ALTER TABLE ldap_entries ADD
CONSTRAINT UNQ1_ldap_entries UNIQUE
(
objclass,
keyval
);
ALTER TABLE ldap_entries ADD
CONSTRAINT UNQ2_ldap_entries UNIQUE
(
dn
);
ALTER TABLE ldap_objclasses ADD
CONSTRAINT UNQ_ldap_objclasses UNIQUE
(
name
);
CREATE SEQUENCE ldap_objclass_ids START WITH 1 INCREMENT BY 1;
CREATE SEQUENCE ldap_attr_ids START WITH 1 INCREMENT BY 1;
CREATE SEQUENCE ldap_entry_ids START WITH 1 INCREMENT BY 1;

View file

@ -0,0 +1,190 @@
CREATE TABLE persons (
id NUMBER NOT NULL,
name varchar2(255) NOT NULL
);
CREATE TABLE institutes (
id NUMBER NOT NULL,
name varchar2(255)
);
CREATE TABLE documents (
id NUMBER NOT NULL,
title varchar2(255) NOT NULL,
abstract varchar2(255)
);
CREATE TABLE authors_docs (
pers_id NUMBER NOT NULL,
doc_id NUMBER NOT NULL
);
CREATE TABLE phones (
id NUMBER NOT NULL ,
phone varchar2(255) NOT NULL ,
pers_id NUMBER NOT NULL
);
ALTER TABLE authors_docs ADD
CONSTRAINT PK_authors_docs PRIMARY KEY
(
pers_id,
doc_id
);
ALTER TABLE documents ADD
CONSTRAINT PK_documents PRIMARY KEY
(
id
);
ALTER TABLE institutes ADD
CONSTRAINT PK_institutes PRIMARY KEY
(
id
);
ALTER TABLE persons ADD
CONSTRAINT PK_persons PRIMARY KEY
(
id
);
ALTER TABLE phones ADD
CONSTRAINT PK_phones PRIMARY KEY
(
id
);
CREATE SEQUENCE person_ids START WITH 1 INCREMENT BY 1;
CREATE SEQUENCE document_ids START WITH 1 INCREMENT BY 1;
CREATE SEQUENCE institute_ids START WITH 1 INCREMENT BY 1;
CREATE SEQUENCE phone_ids START WITH 1 INCREMENT BY 1;
CREATE OR REPLACE PROCEDURE create_person(keyval OUT NUMBER) AS
BEGIN
INSERT INTO persons (id,name) VALUES (person_ids.nextval,' ');
SELECT person_ids.currval INTO keyval FROM DUAL;
END;
/
CREATE OR REPLACE PROCEDURE delete_person(keyval IN NUMBER) AS
BEGIN
DELETE FROM phones WHERE pers_id=keyval;
DELETE FROM authors_docs WHERE pers_id=keyval;
DELETE FROM persons WHERE id=keyval;
END;
/
CREATE OR REPLACE PROCEDURE create_org(keyval OUT NUMBER) AS
BEGIN
INSERT INTO institutes (id,name) VALUES (institute_ids.nextval,' ');
SELECT institute_ids.currval INTO keyval FROM DUAL;
END;
/
CREATE OR REPLACE PROCEDURE delete_org(keyval IN NUMBER) AS
BEGIN
DELETE FROM institutes WHERE id=keyval;
END;
/
CREATE OR REPLACE PROCEDURE create_document(keyval OUT NUMBER) AS
BEGIN
INSERT INTO documents (id,title) VALUES (document_ids.nextval,' ');
SELECT document_ids.currval INTO keyval FROM DUAL;
END;
/
CREATE OR REPLACE PROCEDURE delete_document (keyval IN NUMBER) AS
BEGIN
DELETE FROM authors_docs WHERE doc_id=keyval;
DELETE FROM documents WHERE id=keyval;
END;
/
CREATE OR REPLACE PROCEDURE add_phone(pers_id IN NUMBER, phone IN varchar2) AS
BEGIN
INSERT INTO phones (id,pers_id,phone) VALUES (phone_ids.nextval,pers_id,phone);
END;
/
CREATE OR REPLACE PROCEDURE delete_phone(keyval IN NUMBER, phone IN varchar2) AS
BEGIN
DELETE FROM phones WHERE pers_id=keyval AND phone=phone;
END;
/
CREATE OR REPLACE PROCEDURE set_person_name(keyval IN NUMBER, new_name IN varchar2) AS
BEGIN
UPDATE persons SET name=new_name WHERE id=keyval;
END;
/
CREATE OR REPLACE PROCEDURE set_org_name(keyval IN NUMBER, new_name IN varchar2) AS
BEGIN
UPDATE institutes SET name=new_name WHERE id=keyval;
END;
/
CREATE OR REPLACE PROCEDURE set_doc_title (keyval IN NUMBER, new_title IN varchar2) AS
BEGIN
UPDATE documents SET title=new_title WHERE id=keyval;
END;
/
CREATE OR REPLACE PROCEDURE set_doc_abstract (keyval IN NUMBER, new_abstract IN varchar2) AS
BEGIN
UPDATE documents SET abstract=new_abstract WHERE id=keyval;
END;
/
CREATE OR REPLACE PROCEDURE make_author_link (keyval IN NUMBER, author_dn IN varchar2) 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);
END IF;
END;
/
CREATE OR REPLACE PROCEDURE make_doc_link (keyval IN NUMBER, doc_dn IN varchar2) 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);
END IF;
END;
/
CREATE OR REPLACE PROCEDURE del_doc_link (keyval IN NUMBER, doc_dn IN varchar2) 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;
END IF;
END;
/
CREATE PROCEDURE del_author_link (keyval IN NUMBER, author_dn IN varchar2) 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
DELETE FROM authors_docs WHERE doc_id=keyval AND pers_id=per_id;
END IF;
END;
/

View file

@ -0,0 +1,7 @@
DROP TABLE ldap_attrs;
DROP TABLE ldap_entries;
DROP TABLE ldap_objclasses;
DROP SEQUENCE ldap_entry_ids;
DROP SEQUENCE ldap_attr_ids;
DROP SEQUENCE ldap_objclass_ids;

View file

@ -0,0 +1,25 @@
DROP TABLE persons;
DROP TABLE institutes;
DROP TABLE documents;
DROP TABLE authors_docs;
DROP TABLE phones;
DROP SEQUENCE person_ids;
DROP SEQUENCE institute_ids;
DROP SEQUENCE document_ids;
DROP SEQUENCE phone_ids;
DROP PROCEDURE create_person;
DROP PROCEDURE delete_person;
DROP PROCEDURE add_phone;
DROP PROCEDURE delete_phone;
DROP PROCEDURE set_person_name;
DROP PROCEDURE set_org_name;
DROP PROCEDURE set_doc_title;
DROP PROCEDURE set_doc_abstract;
DROP PROCEDURE create_document;
DROP PROCEDURE create_org;
DROP PROCEDURE delete_document;
DROP PROCEDURE delete_org;
DROP PROCEDURE make_doc_link;
DROP PROCEDURE del_doc_link;
DROP PROCEDURE make_author_link;
DROP PROCEDURE del_author_link;

View file

@ -0,0 +1,41 @@
# $OpenLDAP$
#
# See slapd.conf(5) for details on configuration options.
# This file should NOT be world readable.
#
include ./slapd.at.conf
include ./slapd.oc.conf
# Define global ACLs to disable default read access.
# Do not enable referrals until AFTER you have a working directory
# service AND an understanding of referrals.
#referral ldap://root.openldap.org
pidfile ./slapd.pid
argsfile ./slapd.args
#######################################################################
# ldbm database definitions
#######################################################################
#database ldbm
#suffix "dc=your-domain, dc=com"
#suffix "o=Your Organization Name, c=US"
#directory /usr/tmp
#rootdn "cn=root, dc=your-domain, dc=com"
#rootdn "cn=root, o=Your Organization Name, c=US"
#rootpw secret
# cleartext passwords, especially for the rootdn, should
# be avoid. See slapd.conf(5) for details.
database sql
suffix "o=sql,c=RU"
rootdn "cn=root,o=sql,c=RU"
rootpw secret
#dbname ldap_ora8_ms
dbname ldap_ora8
dbuser ldap
dbpasswd ldap
subtree_cond "ldap_entries.dn LIKE CONCAT('%',?)"
insentry_query "INSERT INTO ldap_entries (id,dn,objclass,parent,keyval) VALUES (ldap_entry_ids.nextval,?,?,?,?)"

View file

@ -0,0 +1,45 @@
insert into institutes (id,name) values (institute_ids.nextval,'sql');
insert into persons (id,name) values (person_ids.nextval,'Mitya Kovalev');
insert into persons (id,name) values (person_ids.nextval,'Torvlobnor Puzdoy');
insert into persons (id,name) values (person_ids.nextval,'Akakiy Zinberstein');
insert into phones (id,phone,pers_id) values (phone_ids.nextval,'332-2334',1);
insert into phones (id,phone,pers_id) values (phone_ids.nextval,'222-3234',1);
insert into phones (id,phone,pers_id) values (phone_ids.nextval,'545-4563',2);
insert into documents (id,abstract,title) values (document_ids.nextval,'abstract1','book1');
insert into documents (id,abstract,title) values (document_ids.nextval,'abstract2','book2');
insert into authors_docs (pers_id,doc_id) values (1,1);
insert into authors_docs (pers_id,doc_id) values (1,2);
insert into authors_docs (pers_id,doc_id) values (2,1);
insert into ldap_entries (id,dn,objclass,parent,keyval)
values (ldap_entry_ids.nextval,'o=sql,c=RU',3,0,1);
insert into ldap_entries (id,dn,objclass,parent,keyval)
values (ldap_entry_ids.nextval,'cn=Mitya Kovalev,o=sql,c=RU',1,1,1);
insert into ldap_entries (id,dn,objclass,parent,keyval)
values (ldap_entry_ids.nextval,'cn=Torvlobnor Puzdoy,o=sql,c=RU',1,1,2);
insert into ldap_entries (id,dn,objclass,parent,keyval)
values (ldap_entry_ids.nextval,'cn=Akakiy Zinberstein,o=sql,c=RU',1,1,3);
insert into ldap_entries (id,dn,objclass,parent,keyval)
values (ldap_entry_ids.nextval,'documentTitle=book1,o=sql,c=RU',2,1,1);
insert into ldap_entries (id,dn,objclass,parent,keyval)
values (ldap_entry_ids.nextval,'documentTitle=book2,o=sql,c=RU',2,1,2);

View file

@ -0,0 +1,49 @@
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)
values (2,'document','documents','id','{call create_document(?)}','{call delete_document(?)}');
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_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,'{call set_person_name(?,?)}',
NULL,NULL);
insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc)
values (2,1,'telephoneNumber','phones.phone','persons,phones',
'phones.pers_id=persons.id','{call add_phone(?,?)}',
NULL,'{call delete_phone(?,?)}');
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,'{call set_person_name(?,?)}',
NULL,NULL);
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,'{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)
values (5,2,'documentTitle','documents.title','documents',NULL,'{call set_doc_title(?,?)}',
NULL,NULL);
insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc)
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);
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,'{call set_org_name(?,?)}',
NULL,NULL);
insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc)
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(?,?)}');
insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc)
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(?,?)}');

View file

@ -0,0 +1,235 @@
/*
* 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 <stdio.h>
#include <sys/types.h>
#include <string.h>
#include "slap.h"
#include "back-sql.h"
#include "sql-wrap.h"
#include "schema-map.h"
#include "util.h"
int backsql_dummy(void *,void *);
int backsql_cmp_oc_name(backsql_oc_map_rec *m1,backsql_oc_map_rec *m2)
{
return strcasecmp(m1->name,m2->name);
}
int backsql_cmp_oc_id(backsql_oc_map_rec *m1,backsql_oc_map_rec *m2)
{
if (m1->id < m2->id)
return -1;
if (m1->id > m2->id)
return 1;
return 0;
}
int backsql_cmp_attr(backsql_at_map_rec *m1,backsql_at_map_rec *m2)
{
return strcasecmp(m1->name,m2->name);
}
int backsql_load_schema_map(backsql_info *si,SQLHDBC dbh)
{
SQLHSTMT oc_sth,at_sth;
RETCODE rc;
BACKSQL_ROW_NTS oc_row,at_row;
unsigned long oc_id;
backsql_oc_map_rec *oc_map;
backsql_at_map_rec *at_map;
char *tmps;
int tmpslen;
Debug(LDAP_DEBUG_TRACE,"==>load_schema_map()\n",0,0,0);
rc=backsql_Prepare(dbh,&oc_sth,si->oc_query,0);
if (rc != SQL_SUCCESS)
{
Debug(LDAP_DEBUG_TRACE,"load_schema_map(): error preparing oc_query: '%s'\n",si->oc_query,0,0);
backsql_PrintErrors(si->db_env,dbh,oc_sth,rc);
return -1;
}
rc=backsql_Prepare(dbh,&at_sth,si->at_query,0);
if (rc != SQL_SUCCESS)
{
Debug(LDAP_DEBUG_TRACE,"load_schema_map(): error preparing at_query: '%s'\n",si->at_query,0,0);
backsql_PrintErrors(si->db_env,dbh,at_sth,rc);
return -1;
}
if ((rc=backsql_BindParamID(at_sth,1,&oc_id)) != SQL_SUCCESS)
{
Debug(LDAP_DEBUG_TRACE,"load_schema_map(): error binding param for at_query: \n",0,0,0);
backsql_PrintErrors(si->db_env,dbh,at_sth,rc);
return -1;
}
if ((rc=SQLExecute(oc_sth)) != SQL_SUCCESS)
{
Debug(LDAP_DEBUG_TRACE,"load_schema_map(): error executing oc_query: \n",0,0,0);
backsql_PrintErrors(si->db_env,dbh,oc_sth,rc);
return -1;
}
backsql_BindRowAsStrings(oc_sth,&oc_row);
while ((rc=SQLFetch(oc_sth)) == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO)
{
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->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);
if ((rc=SQLExecute(at_sth)) != SQL_SUCCESS)
{
Debug(LDAP_DEBUG_TRACE,"load_schema_map(): error executing at_query: \n",0,0,0);
backsql_PrintErrors(SQL_NULL_HENV,dbh,at_sth,rc);
return -1;
}
backsql_BindRowAsStrings(at_sth,&at_row);
while ((rc=SQLFetch(at_sth)) == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO)
{
Debug(LDAP_DEBUG_TRACE,"********'%s'\n",at_row.cols[0],0,0);
Debug(LDAP_DEBUG_TRACE,"name='%s',sel_expr='%s' from='%s' ",at_row.cols[0],
at_row.cols[1],at_row.cols[2]);
Debug(LDAP_DEBUG_TRACE,"join_where='%s',add_proc='%s' modify_proc='%s' ",at_row.cols[3],
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]);
tmps=NULL;tmpslen=0;
backsql_merge_from_clause(&tmps,&tmpslen,at_row.cols[2]);
at_map->from_tbls=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]);
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);
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);
}
backsql_FreeRow(&at_row);
SQLFreeStmt(at_sth,SQL_CLOSE);
}
backsql_FreeRow(&oc_row);
SQLFreeStmt(at_sth,SQL_DROP);
SQLFreeStmt(oc_sth,SQL_DROP);
si->schema_loaded=1;
Debug(LDAP_DEBUG_TRACE,"<==load_schema_map()\n",0,0,0);
return 1;
}
backsql_oc_map_rec* backsql_oc_with_name(backsql_info *si,char* objclass)
{
backsql_oc_map_rec tmp,*res;
// Debug(LDAP_DEBUG_TRACE,"==>oc_with_name(): searching for objectclass with name='%s'\n",objclass,0,0);
tmp.name=objclass;
res=(backsql_oc_map_rec*)avl_find(si->oc_by_name,&tmp,(AVL_CMP)backsql_cmp_oc_name);
// if (res!=NULL)
// Debug(LDAP_DEBUG_TRACE,"<==oc_with_name(): found name='%s', id=%d\n",res->name,res->id,0);
// else
// Debug(LDAP_DEBUG_TRACE,"<==oc_with_name(): not found\n",0,0,0);
return res;
}
backsql_oc_map_rec* backsql_oc_with_id(backsql_info *si,unsigned long id)
{
backsql_oc_map_rec tmp,*res;
// Debug(LDAP_DEBUG_TRACE,"==>oc_with_id(): searching for objectclass with id='%d'\n",id,0,0);
tmp.id=id;
res=(backsql_oc_map_rec*)avl_find(si->oc_by_id,&tmp,(AVL_CMP)backsql_cmp_oc_id);
// if (res!=NULL)
// Debug(LDAP_DEBUG_TRACE,"<==oc_with_name(): found name='%s', id=%d\n",res->name,res->id,0);
// else
// Debug(LDAP_DEBUG_TRACE,"<==oc_with_name(): not found\n",0,0,0);
return res;
}
backsql_at_map_rec* backsql_at_with_name(backsql_oc_map_rec* objclass,char* attr)
{
backsql_at_map_rec tmp,*res;
//Debug(LDAP_DEBUG_TRACE,"==>at_with_name(): searching for attribute with name='%s' (for objectclass '%s')\n",
// attr,objclass->name,0);
tmp.name=attr;
res=(backsql_at_map_rec*)avl_find(objclass->attrs,&tmp,(AVL_CMP)backsql_cmp_attr);
//if (res!=NULL)
//Debug(LDAP_DEBUG_TRACE,"<==at_with_name(): found name='%s', sel_expr='%s'\n",
// res->name,res->sel_expr,0);
//else
// Debug(LDAP_DEBUG_TRACE,"<==at_with_name(): not found\n",0,0,0);
return res;
}
int backsql_free_attr(backsql_at_map_rec *at)
{
Debug(LDAP_DEBUG_TRACE,"==>free_attr(): '%s'\n",at->name,0,0);
ch_free(at->name);
ch_free(at->sel_expr);
if (at->from_tbls!=NULL)
ch_free(at->from_tbls);
if (at->join_where!=NULL)
ch_free(at->join_where);
if (at->add_proc!=NULL)
ch_free(at->add_proc);
if (at->modify_proc!=NULL)
ch_free(at->modify_proc);
if (at->delete_proc!=NULL)
ch_free(at->delete_proc);
if (at->query)
ch_free(at->query);
ch_free(at);
Debug(LDAP_DEBUG_TRACE,"<==free_attr()\n",0,0,0);
return 1;
}
int backsql_free_oc(backsql_oc_map_rec *oc)
{
Debug(LDAP_DEBUG_TRACE,"==>free_oc(): '%s'\n",oc->name,0,0);
avl_free(oc->attrs,(AVL_FREE)backsql_free_attr);
ch_free(oc->name);
ch_free(oc->keytbl);
ch_free(oc->keycol);
if (oc->create_proc!=NULL)
ch_free(oc->create_proc);
if (oc->delete_proc!=NULL)
ch_free(oc->delete_proc);
ch_free(oc);
Debug(LDAP_DEBUG_TRACE,"<==free_oc()\n",0,0,0);
return 1;
}
int backsql_destroy_schema_map(backsql_info *si)
{
Debug(LDAP_DEBUG_TRACE,"==>destroy_schema_map()\n",0,0,0);
avl_free(si->oc_by_id,(AVL_FREE)backsql_free_oc);
avl_free(si->oc_by_name,(AVL_FREE)backsql_dummy);
Debug(LDAP_DEBUG_TRACE,"<==destroy_schema_map()\n",0,0,0);
return 0;
}

View file

@ -0,0 +1,506 @@
/*
* 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 <stdio.h>
#include <sys/types.h>
#include <string.h>
#include "slap.h"
#include "back-sql.h"
#include "sql-wrap.h"
#include "schema-map.h"
#include "entry-id.h"
#include "util.h"
int backsql_attrlist_add(backsql_srch_info *bsi,char *at_name)
{
char **p=bsi->attrs;
int n_attrs=0;
if (bsi->attrs==NULL)
return 1;
while(*p)
{
Debug(LDAP_DEBUG_TRACE,"==>backsql_attrlist_add(): attribute '%s' is in list\n",*p,0,0);
if (!strcasecmp(*p,at_name))
return 1;
n_attrs++;
p++;
}
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+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)
{
char **p;
bsi->base_dn=nbase;
bsi->scope=scope;
bsi->slimit=slimit;
bsi->tlimit=tlimit;
bsi->filter=filter;
bsi->dbh=dbh;
bsi->be=be;
bsi->conn=conn;
bsi->op=op;
if (attrs!=NULL)
{
bsi->attrs=(char**)ch_calloc(1,sizeof(char*));
bsi->attrs[0]=NULL;
for(p=attrs;*p!=NULL;p++)
backsql_attrlist_add(bsi,*p);
}
else
bsi->attrs=attrs;
bsi->abandon=0;
bsi->id_list=NULL;
bsi->stoptime=stoptime;
bsi->bi=bi;
bsi->sel=NULL; bsi->from=NULL; bsi->join_where=NULL; bsi->flt_where=NULL;
bsi->sel_len=0; bsi->from_len=0; bsi->jwhere_len=0; bsi->fwhere_len=0;
}
int backsql_process_filter_list(backsql_srch_info *bsi,Filter *f,int op)
{
char *sub_clause=NULL;
int len=0,res;
bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,"(",NULL);
while(1)
{
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;
switch (op)
{
case LDAP_FILTER_AND:
bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len," AND ",NULL);
break;
case LDAP_FILTER_OR:
bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len," OR ",NULL);
break;
}
}
bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,")",NULL);
return 1;
}
int backsql_process_sub_filter(backsql_srch_info *bsi,Filter *f)
{
int i;
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,
" 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,"%",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);
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,"')",NULL);
return 1;
}
int backsql_process_filter(backsql_srch_info *bsi,Filter *f)
{
backsql_at_map_rec *at;
backsql_at_map_rec oc_attr={"objectClass","","",NULL,NULL,NULL,NULL};
char *at_name=NULL;
int done=0,len=0;
Debug(LDAP_DEBUG_TRACE,"==>backsql_process_filter()\n",0,0,0);
switch(f->f_choice)
{
case LDAP_FILTER_OR:
backsql_process_filter_list(bsi,f->f_or,LDAP_FILTER_OR);
done=1;
break;
case LDAP_FILTER_AND:
backsql_process_filter_list(bsi,f->f_and,LDAP_FILTER_AND);
done=1;
break;
case LDAP_FILTER_NOT:
bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,"NOT (",NULL);
backsql_process_filter(bsi,f->f_not);
bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,")",NULL);
done=1;
break;
case LDAP_FILTER_PRESENT:
at_name=f->f_type;
break;
default:
at_name=f->f_avtype;
break;
}
if (done)
goto done;
if (strcasecmp(at_name,"objectclass"))
at=backsql_at_with_name(bsi->oc,at_name);
else
{
at=&oc_attr;
at->sel_expr=backsql_strcat(at->sel_expr,&len,"'",bsi->oc->name,"'",NULL);
}
if (at==NULL)
{
Debug(LDAP_DEBUG_TRACE,"backsql_process_filter(): attribute '%s' is not defined for objectclass '%s'\n",
at_name,bsi->oc->name,0);
return -1;
}
backsql_merge_from_clause(&bsi->from,&bsi->from_len,at->from_tbls);
//need to add this attribute to list of attrs to load, so that we could do test_filter() later
backsql_attrlist_add(bsi,at_name);
if (at->join_where != NULL && strstr(bsi->join_where,at->join_where)==NULL)
bsi->join_where=backsql_strcat(bsi->join_where,&bsi->jwhere_len," AND ",at->join_where,NULL);
//if (at!=&oc_attr)
// bsi->sel=backsql_strcat(bsi->sel,&bsi->sel_len,",",at->sel_expr," AS ",at->name,NULL);
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);
break;
case LDAP_FILTER_GE:
bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,"(",at->sel_expr,">=",
f->f_avvalue.bv_val,")",NULL);
break;
case LDAP_FILTER_LE:
bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,"(",at->sel_expr,"<=",
f->f_avvalue.bv_val,")",NULL);
break;
case LDAP_FILTER_PRESENT:
bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,"NOT (",at->sel_expr,
" IS NULL)",NULL);
break;
case LDAP_FILTER_SUBSTRINGS:
backsql_process_sub_filter(bsi,f);
break;
}
done:
if (oc_attr.sel_expr!=NULL)
free(oc_attr.sel_expr);
Debug(LDAP_DEBUG_TRACE,"<==backsql_process_filter()\n",0,0,0);
return 1;
}
char* backsql_srch_query(backsql_srch_info *bsi)
{
char *query=NULL;
int q_len=0;
Debug(LDAP_DEBUG_TRACE,"==>backsql_srch_query()\n",0,0,0);
bsi->sel=NULL;
bsi->from=NULL;
bsi->join_where=NULL;
bsi->flt_where=NULL;
bsi->sel_len=bsi->from_len=bsi->jwhere_len=bsi->fwhere_len=0;
bsi->sel=backsql_strcat(bsi->sel,&bsi->sel_len,
"SELECT ldap_entries.id,",bsi->oc->keytbl,".",bsi->oc->keycol,
", '",bsi->oc->name,"' AS objectClass",
", ldap_entries.dn AS dn",
NULL);
bsi->from=backsql_strcat(bsi->from,&bsi->from_len," FROM ldap_entries,",bsi->oc->keytbl,NULL);
bsi->join_where=backsql_strcat(bsi->join_where,&bsi->jwhere_len," WHERE ",
bsi->oc->keytbl,".",bsi->oc->keycol,"=ldap_entries.keyval AND ",
"ldap_entries.objclass=? AND ",NULL);
switch(bsi->scope)
{
case LDAP_SCOPE_BASE:
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,
"ldap_entries.parent=?",NULL);
break;
case LDAP_SCOPE_SUBTREE:
bsi->join_where=backsql_strcat(bsi->join_where,&bsi->jwhere_len,
bsi->bi->subtree_cond,NULL);
break;
}
if (backsql_process_filter(bsi,bsi->filter))
query=backsql_strcat(query,&q_len,bsi->sel,bsi->from,bsi->join_where," AND ",bsi->flt_where,NULL);
free(bsi->sel);
free(bsi->from);
free(bsi->join_where);
free(bsi->flt_where);
bsi->sel_len=bsi->from_len=bsi->jwhere_len=bsi->fwhere_len=0;
Debug(LDAP_DEBUG_TRACE,"<==backsql_srch_query()\n",0,0,0);
return query;
}
int backsql_oc_get_candidates(backsql_oc_map_rec *oc,backsql_srch_info *bsi)
{
char *query=NULL;
SQLHSTMT sth;
RETCODE rc;
backsql_entryID base_id,*res,*c_id;
//Entry *e;
BACKSQL_ROW_NTS row;
//int i;
Debug(LDAP_DEBUG_TRACE,"==>backsql_oc_get_candidates(): oc='%s'\n",oc->name,0,0);
bsi->oc=oc;
query=backsql_srch_query(bsi);
if (query==NULL)
{
Debug(LDAP_DEBUG_TRACE,"backsql_oc_get_candidates(): could not construct query for objectclass\n",0,0,0);
return 1;
}
Debug(LDAP_DEBUG_TRACE,"Constructed query: %s\n",query,0,0);
if ((rc=backsql_Prepare(bsi->dbh,&sth,query,0)) != SQL_SUCCESS)
{
Debug(LDAP_DEBUG_TRACE,"backsql_oc_get_candidates(): error preparing query\n",0,0,0);
backsql_PrintErrors(bsi->bi->db_env,bsi->dbh,sth,rc);
free(query);
return 1;
}
free(query);
if (backsql_BindParamID(sth,1,&bsi->oc->id) != SQL_SUCCESS)
{
Debug(LDAP_DEBUG_TRACE,"backsql_oc_get_candidates(): error binding objectclass id parameter\n",0,0,0);
return 1;
}
switch(bsi->scope)
{
case LDAP_SCOPE_BASE:
case LDAP_SCOPE_SUBTREE:
if ((rc=backsql_BindParamStr(sth,2,bsi->base_dn,BACKSQL_MAX_DN_LEN)) != SQL_SUCCESS)
{
Debug(LDAP_DEBUG_TRACE,"backsql_oc_get_candidates(): error binding base_dn parameter\n",0,0,0);
backsql_PrintErrors(bsi->bi->db_env,bsi->dbh,sth,rc);
return 1;
}
break;
case LDAP_SCOPE_ONELEVEL:
res=backsql_dn2id(&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);
bsi->status=LDAP_NO_SUCH_OBJECT;
return 0;
}
if (backsql_BindParamID(sth,2,&base_id.id) != SQL_SUCCESS)
{
Debug(LDAP_DEBUG_TRACE,"backsql_oc_get_candidates(): error binding base id parameter\n",0,0,0);
free(base_id.dn);
return 1;
}
free(base_id.dn);
break;
}
if ((rc=SQLExecute(sth)) != SQL_SUCCESS && rc!= SQL_SUCCESS_WITH_INFO)
{
Debug(LDAP_DEBUG_TRACE,"backsql_oc_get_candidates(): error executing query\n",0,0,0);
backsql_PrintErrors(bsi->bi->db_env,bsi->dbh,sth,rc);
SQLFreeStmt(sth,SQL_DROP);
return 1;
}
backsql_BindRowAsStrings(sth,&row);
while ((rc=SQLFetch(sth)) == SQL_SUCCESS || rc==SQL_SUCCESS_WITH_INFO)
{
/*
e=(Entry*)ch_calloc(1,sizeof(Entry));
for (i=1;i<row.ncols;i++)
{
if (row.is_null[i]>0)
{
backsql_entry_addattr(e,row.col_names[i],row.cols[i],row.col_prec[i]);
// Debug(LDAP_DEBUG_TRACE,"prec=%d\n",(int)row.col_prec[i],0,0);
}
// else
// Debug(LDAP_DEBUG_TRACE,"NULL value in this row for attribute '%s'\n",row.col_names[i],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->next=bsi->id_list;
bsi->id_list=c_id;
}
backsql_FreeRow(&row);
SQLFreeStmt(sth,SQL_DROP);
Debug(LDAP_DEBUG_TRACE,"<==backsql_oc_get_candidates()\n",0,0,0);
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)
{
backsql_info *bi=(backsql_info*)be->be_private;
SQLHDBC dbh;
int sres;
int nentries;
Entry entry,*res;
int manageDSAit = get_manageDSAit( op );
struct berval **v2refs = NULL;
time_t stoptime;
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);
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);
if (!dbh)
{
Debug(LDAP_DEBUG_TRACE,"backsql_search(): could not get connection handle - exiting\n",0,0,0);
send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
return 1;
}
if (tlimit == 0 && be_isroot(be,op->o_dn))
{
tlimit = -1; /* allow root to set no limit */
}
else
{
tlimit = (tlimit > be->be_timelimit || tlimit < 1) ?
be->be_timelimit : tlimit;
stoptime = op->o_time + tlimit;
}
if (slimit == 0 && be_isroot(be,op->o_dn))
{
slimit = -1; /* allow root to set no limit */
}
else
{
slimit = (slimit > be->be_sizelimit || slimit < 1) ?
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);
//for each objectclass we try to construct query which gets IDs
//of entries matching LDAP query filter and scope (or at least candidates),
//and get the IDs
avl_apply(bi->oc_by_name,(AVL_APPLY)backsql_oc_get_candidates,&srch_info,0,AVL_INORDER);
nentries=0;
//now we load candidate entries (only those attrubutes mentioned in attrs and filter),
//test it against full filter and then send to client
for(eid=srch_info.id_list;eid!=NULL;eid=eid->next)
{
/* check for abandon */
ldap_pvt_thread_mutex_lock(&op->o_abandonmutex);
if (op->o_abandon)
{
ldap_pvt_thread_mutex_unlock(&op->o_abandonmutex);
break;
}
ldap_pvt_thread_mutex_unlock(&op->o_abandonmutex);
/* check time limit */
if ( tlimit != -1 && slap_get_time() > stoptime)
{
send_search_result( conn, op, LDAP_TIMELIMIT_EXCEEDED,
NULL, NULL, v2refs, NULL, nentries );
break;
}
Debug(LDAP_DEBUG_TRACE,"backsql_search(): loading data for entry id=%d, oc_id=%d, keyval=%d\n",
eid->id,eid->oc_id,eid->keyval);
res=backsql_id2entry(&srch_info,&entry,eid);
if (res==NULL)
{
Debug(LDAP_DEBUG_TRACE,"backsql_search(): error in backsql_id2entry() - skipping entry\n",0,0,0);
continue;
}
if ( !manageDSAit && scope != LDAP_SCOPE_BASE &&
is_entry_referral( &entry ) )
{
struct berval **refs = get_entry_referrals(be,conn,op,&entry);
send_search_reference( be, conn, op, &entry, refs, scope, NULL, &v2refs );
ber_bvecfree( refs );
continue;
}
// if (test_filter(be,conn,op,&entry,filter)==0)
{
if ((sres=send_search_entry(be,conn,op,&entry,attrs,attrsonly,NULL))==-1)
{
Debug(LDAP_DEBUG_TRACE,"backsql_search(): connection lost\n",0,0,0);
break;
}
nentries+=!sres;
}
}
for(eid=srch_info.id_list;eid!=NULL;eid=backsql_free_entryID(eid));
//free bsi->attrs!!!!!!!!!!!!!!!!!!!!!!!!!!!
if (nentries>0)
send_search_result( conn, op,
v2refs == NULL ? LDAP_SUCCESS : LDAP_REFERRAL,
NULL, NULL, v2refs, NULL, nentries );
else
send_ldap_result(conn,op,LDAP_NO_SUCH_OBJECT,NULL,NULL,NULL,0);
Debug(LDAP_DEBUG_TRACE,"<==backsql_search()\n",0,0,0);
return 0;
}

View file

@ -0,0 +1,313 @@
/*
* 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 <stdio.h>
#include <string.h>
#include <sys/types.h>
#include "slap.h"
#include "back-sql.h"
#include "sql-types.h"
#include "sql-wrap.h"
#include "schema-map.h"
#define MAX_ATTR_LEN 16384
typedef struct backsql_conn
{
int ldap_cid;
SQLHDBC dbh;
}backsql_db_conn;
int backsql_dummy(void *,void *);
void backsql_PrintErrors(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT sth,int rc)
{
SQLCHAR msg[SQL_MAX_MESSAGE_LENGTH]; /* msg. buffer */
SQLCHAR state[SQL_SQLSTATE_SIZE]; /* statement buf. */
SDWORD iSqlCode; /* return code */
SWORD len=SQL_MAX_MESSAGE_LENGTH-1; /* return length */
Debug(LDAP_DEBUG_TRACE,"Return code: %d\n", rc,0,0);
while((rc=SQLError(henv,hdbc,sth,state,&iSqlCode,msg,
SQL_MAX_MESSAGE_LENGTH - 1, &len)) == SQL_SUCCESS
|| rc == SQL_SUCCESS_WITH_INFO
)
{
Debug(LDAP_DEBUG_TRACE,"SQL engine state: %s\n", state,0,0);
Debug(LDAP_DEBUG_TRACE,"Native error code: %d\n",(int) iSqlCode,0,0);
Debug(LDAP_DEBUG_TRACE,"Message: %s\n",msg,0,0);
}
}
RETCODE backsql_Prepare(SQLHDBC dbh,SQLHSTMT *sth,char* query,int timeout)
{
RETCODE rc;
char drv_name[30];
SWORD len;
int i;
rc=SQLAllocStmt(dbh,sth);
if (rc != SQL_SUCCESS)
return rc;
//Debug(LDAP_DEBUG_TRACE,"==>_SQLPrepare()\n", 0,0,0);
SQLGetInfo(dbh,SQL_DRIVER_NAME,drv_name,30,&len);
//Debug(LDAP_DEBUG_TRACE,"_SQLPrepare(): driver name='%s'\n", drv_name,0,0);
for (i=0;i<30 && drv_name[i];i++)
drv_name[i]=toupper(drv_name[i]);
if (!strncmp(drv_name,"SQLSRV32.DLL",30))
{
//stupid default result set in MS SQL Server does not support multiple active statements
//on the same connection -- so we are trying to make it not to use default result set...
Debug(LDAP_DEBUG_TRACE,"_SQLprepare(): enabling MS SQL Server default result set workaround\n", 0,0,0);
rc=SQLSetStmtOption(*sth,SQL_CONCURRENCY,SQL_CONCUR_ROWVER);
if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)
{
Debug(LDAP_DEBUG_TRACE,"_SQLPrepare(): SQLSetStmtOption(SQL_CONCURRENCY,SQL_CONCUR_ROWVER) failed:\n", 0,0,0);
backsql_PrintErrors(SQL_NULL_HENV,dbh,sth,rc);
}
}
if (timeout>0)
{
Debug(LDAP_DEBUG_TRACE,"_SQLprepare(): setting query timeout to %d sec.\n", timeout,0,0);
if ((rc=SQLSetStmtOption(*sth,SQL_QUERY_TIMEOUT,timeout)) != SQL_SUCCESS)
{
backsql_PrintErrors(SQL_NULL_HENV,dbh,sth,rc);
}
}
//Debug(LDAP_DEBUG_TRACE,"<==_SQLPrepare() calling SQLPrepare()\n", 0,0,0);
return SQLPrepare(*sth,query,SQL_NTS);
}
RETCODE backsql_BindParamStr(SQLHSTMT sth,int par_ind,char *str,int maxlen)
{
RETCODE rc;
SQLINTEGER len=SQL_NTS;
rc=SQLBindParameter(sth,(SQLUSMALLINT)par_ind,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_VARCHAR,
(SQLUINTEGER)maxlen,0,(SQLPOINTER)str,(SQLUINTEGER)maxlen,NULL);
return rc;
}
RETCODE backsql_BindParamID(SQLHSTMT sth,int par_ind,unsigned long *id)
{
return SQLBindParameter(sth,(SQLUSMALLINT)par_ind,SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,
0,0,(SQLPOINTER)id,0,(SQLINTEGER*)NULL);
}
RETCODE backsql_BindRowAsStrings(SQLHSTMT sth,BACKSQL_ROW_NTS *row)
{
RETCODE rc;
SQLCHAR colname[64];
SQLSMALLINT name_len,col_type,col_scale,col_null;
UDWORD col_prec;
int i;
if (row == NULL)
return SQL_ERROR;
//Debug(LDAP_DEBUG_TRACE,"==> backsql_BindRowAsStrings()\n",0,0,0);
rc=SQLNumResultCols(sth,&row->ncols);
if (rc != SQL_SUCCESS)
{
//Debug(LDAP_DEBUG_TRACE,"_SQLBindRowAsStrings(): SQLNumResultCols() failed:\n",0,0,0);
backsql_PrintErrors(SQL_NULL_HENV,SQL_NULL_HDBC,sth,rc);
}
else
{
//Debug(LDAP_DEBUG_TRACE,"backsql_BindRowAsStrings: ncols=%d\n",(int)row->ncols,0,0);
row->col_names=(char**)ch_calloc(row->ncols,sizeof(char*));
row->cols=(char**)ch_calloc(row->ncols,sizeof(char*));
row->col_prec=(UDWORD*)ch_calloc(row->ncols,sizeof(UDWORD));
row->is_null=(SQLINTEGER*)ch_calloc(row->ncols,sizeof(SQLINTEGER));
for (i=1;i<=row->ncols;i++)
{
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);
//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)
{
//row->cols[i-1]=NULL;
//row->col_prec[i-1]=-1;
//such fields must be handled in some other way since they return 2G
//as their precision (at least it does so with MS SQL Server w/native driver)
//for now, we just set fixed precision for such fields - dirty hack, but...
//no time to deal with SQLGetData()
col_prec=MAX_ATTR_LEN;
row->cols[i-1]=(char*)ch_calloc((col_prec+1),sizeof(char));
row->col_prec[i-1]=col_prec;
rc=SQLBindCol(sth,(SQLUSMALLINT)i,SQL_C_CHAR,(SQLPOINTER)row->cols[i-1],col_prec+1,
&row->is_null[i-1]);
}
else
{
row->cols[i-1]=(char*)ch_calloc((col_prec+1),sizeof(char));
row->col_prec[i-1]=col_prec;
rc=SQLBindCol(sth,(SQLUSMALLINT)i,SQL_C_CHAR,(SQLPOINTER)row->cols[i-1],col_prec+1,
&row->is_null[i-1]);
}
}
}
//Debug(LDAP_DEBUG_TRACE,"<== backsql_BindRowAsStrings()\n",0,0,0);
return rc;
}
RETCODE backsql_FreeRow(BACKSQL_ROW_NTS *row)
{
int i;
if (row->cols == NULL)
return SQL_ERROR;
for(i=0;i<row->ncols;i++)
{
free(row->cols[i]);
}
free(row->col_names);
free(row->col_prec);
free(row->cols);
free(row->is_null);
return SQL_SUCCESS;
}
int backsql_cmp_connid(backsql_db_conn *c1,backsql_db_conn *c2)
{
if (c1->ldap_cid > c2->ldap_cid)
return 1;
if (c1->ldap_cid < c2->ldap_cid)
return -1;
return 0;
}
int backsql_close_db_conn(backsql_db_conn *conn)
{
Debug(LDAP_DEBUG_TRACE,"==>backsql_close_db_conn()\n",0,0,0);
SQLDisconnect(conn->dbh);
SQLFreeConnect(conn->dbh);
Debug(LDAP_DEBUG_TRACE,"<==backsql_close_db_conn()\n",0,0,0);
return 1;
}
int backsql_init_db_env(backsql_info *si)
{
RETCODE rc;
Debug(LDAP_DEBUG_TRACE,"==>backsql_init_db_env()\n",0,0,0);
if ((rc=SQLAllocEnv(&si->db_env)) != SQL_SUCCESS)
{
Debug(LDAP_DEBUG_TRACE,"init_db_env: SQLAllocEnv failed:\n",0,0,0);
backsql_PrintErrors(SQL_NULL_HENV,SQL_NULL_HDBC,SQL_NULL_HENV,rc);
}
Debug(LDAP_DEBUG_TRACE,"<==backsql_init_db_env()\n",0,0,0);
return SQL_SUCCESS;
}
int backsql_free_db_env(backsql_info *si)
{
Debug(LDAP_DEBUG_TRACE,"==>backsql_free_db_env()\n",0,0,0);
//Debug(LDAP_DEBUG_TRACE,"free_db_env(): delete AVL tree here!!!\n",0,0,0);
//stop, if frontend waits for all threads to shutdown before calling this --
//then what we are going to delete?? everything is deleted already...
Debug(LDAP_DEBUG_TRACE,"<==backsql_free_db_env()\n",0,0,0);
return SQL_SUCCESS;
}
backsql_db_conn* backsql_open_db_conn(backsql_info *si,int ldap_cid)
{
backsql_db_conn *dbc=(backsql_db_conn*)ch_calloc(1,sizeof(backsql_db_conn));
int rc;
Debug(LDAP_DEBUG_TRACE,"==>backsql_open_db_conn()\n",0,0,0);
dbc->ldap_cid=ldap_cid;
if ((rc=SQLAllocConnect(si->db_env,&dbc->dbh)) != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)
{
Debug(LDAP_DEBUG_TRACE,"backsql_open_db_conn: SQLAllocConnect() failed:\n",0,0,0);
backsql_PrintErrors(si->db_env,SQL_NULL_HDBC,SQL_NULL_HENV,rc);
return NULL;
}
if ((rc=SQLConnect(dbc->dbh,si->dbname,SQL_NTS,si->dbuser,SQL_NTS,
si->dbpasswd,SQL_NTS) != SQL_SUCCESS))
{
if (rc != SQL_SUCCESS_WITH_INFO)
Debug(LDAP_DEBUG_TRACE,"backsql_open_db_conn: SQLConnect() failed:\n",0,0,0);
else
Debug(LDAP_DEBUG_TRACE,"backsql_open_db_conn: SQLConnect() succeeded with info:\n",0,0,0);
backsql_PrintErrors(si->db_env,dbc->dbh,SQL_NULL_HENV,rc);
if (rc != SQL_SUCCESS_WITH_INFO)
return NULL;
}
Debug(LDAP_DEBUG_TRACE,"backsql_open_db_conn(): connected, adding to tree\n",0,0,0);
ldap_pvt_thread_mutex_lock(&si->dbconn_mutex);
avl_insert(&si->db_conns,dbc,(AVL_CMP)backsql_cmp_connid,backsql_dummy);
ldap_pvt_thread_mutex_unlock(&si->dbconn_mutex);
Debug(LDAP_DEBUG_TRACE,"<==backsql_open_db_conn()\n",0,0,0);
return dbc;
}
int backsql_free_db_conn(Backend *be,Connection *ldapc)
{
backsql_info *si=(backsql_info*)be->be_private;
backsql_db_conn tmp,*conn;
Debug(LDAP_DEBUG_TRACE,"==>backsql_free_db_conn()\n",0,0,0);
tmp.ldap_cid=ldapc->c_connid;
ldap_pvt_thread_mutex_lock(&si->dbconn_mutex);
conn=(backsql_db_conn*)avl_delete(&si->db_conns,&tmp,(AVL_CMP)backsql_cmp_connid);
ldap_pvt_thread_mutex_unlock(&si->dbconn_mutex);
//we have one thread per connection, as I understand -- so we can
//get this out of critical section
if (conn!=NULL)
{
Debug(LDAP_DEBUG_TRACE,"backsql_free_db_conn(): closing db connection\n",0,0,0);
backsql_close_db_conn(conn);
}
Debug(LDAP_DEBUG_TRACE,"<==backsql_free_db_conn()\n",0,0,0);
return SQL_SUCCESS;
}
SQLHDBC backsql_get_db_conn(Backend *be,Connection *ldapc)
{
backsql_info *si=(backsql_info*)be->be_private;
backsql_db_conn *dbc;
backsql_db_conn tmp;
Debug(LDAP_DEBUG_TRACE,"==>backsql_get_db_conn()\n",0,0,0);
tmp.ldap_cid=ldapc->c_connid;
//we have one thread per connection, as I understand -- so we do not need
// locking here
dbc=(backsql_db_conn*)avl_find(si->db_conns,&tmp,(AVL_CMP)backsql_cmp_connid);
if (!dbc)
dbc=backsql_open_db_conn(si,ldapc->c_connid);
if (!dbc)
{
Debug(LDAP_DEBUG_TRACE,"backsql_get_db_conn(): could not get connection handle -- returning NULL\n",0,0,0);
return NULL;
}
ldap_pvt_thread_mutex_lock(&si->schema_mutex);
if (!si->schema_loaded)
{
Debug(LDAP_DEBUG_TRACE,"backsql_get_db_conn(): first call -- reading schema map\n",0,0,0);
backsql_load_schema_map(si,dbc->dbh);
}
ldap_pvt_thread_mutex_unlock(&si->schema_mutex);
Debug(LDAP_DEBUG_TRACE,"<==backsql_get_db_conn()\n",0,0,0);
return dbc->dbh;
}