From: Dmitry Kovalev Date: Thu, 16 Mar 2000 19:34:46 +0000 (+0000) Subject: more back-sql files + rdbms_dependent samples X-Git-Tag: LDBM_PRE_GIANT_RWLOCK~3140 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=4e703c5261cd179ab675cdeaca4b0eda88db0977;p=openldap more back-sql files + rdbms_dependent samples --- diff --git a/servers/slapd/back-sql/other.c b/servers/slapd/back-sql/other.c new file mode 100644 index 0000000000..a736b1d63d --- /dev/null +++ b/servers/slapd/back-sql/other.c @@ -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 +#include +#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; +} diff --git a/servers/slapd/back-sql/rdbms_depend/mssql/create.sql b/servers/slapd/back-sql/rdbms_depend/mssql/create.sql new file mode 100644 index 0000000000..654d07f5a4 --- /dev/null +++ b/servers/slapd/back-sql/rdbms_depend/mssql/create.sql @@ -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 diff --git a/servers/slapd/back-sql/rdbms_depend/mssql/create_testdb.sql b/servers/slapd/back-sql/rdbms_depend/mssql/create_testdb.sql new file mode 100644 index 0000000000..1040e580ec --- /dev/null +++ b/servers/slapd/back-sql/rdbms_depend/mssql/create_testdb.sql @@ -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 diff --git a/servers/slapd/back-sql/rdbms_depend/mssql/drop.sql b/servers/slapd/back-sql/rdbms_depend/mssql/drop.sql new file mode 100644 index 0000000000..2773ab811b --- /dev/null +++ b/servers/slapd/back-sql/rdbms_depend/mssql/drop.sql @@ -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 + diff --git a/servers/slapd/back-sql/rdbms_depend/mssql/drop_testdb.sql b/servers/slapd/back-sql/rdbms_depend/mssql/drop_testdb.sql new file mode 100644 index 0000000000..4842ed8920 --- /dev/null +++ b/servers/slapd/back-sql/rdbms_depend/mssql/drop_testdb.sql @@ -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 + diff --git a/servers/slapd/back-sql/rdbms_depend/mssql/slapd.conf b/servers/slapd/back-sql/rdbms_depend/mssql/slapd.conf new file mode 100644 index 0000000000..386fb93517 --- /dev/null +++ b/servers/slapd/back-sql/rdbms_depend/mssql/slapd.conf @@ -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 '%'+?" diff --git a/servers/slapd/back-sql/rdbms_depend/mssql/test_data.sql b/servers/slapd/back-sql/rdbms_depend/mssql/test_data.sql new file mode 100644 index 0000000000..a166969d99 --- /dev/null +++ b/servers/slapd/back-sql/rdbms_depend/mssql/test_data.sql @@ -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 diff --git a/servers/slapd/back-sql/rdbms_depend/mssql/test_metadata.sql b/servers/slapd/back-sql/rdbms_depend/mssql/test_metadata.sql new file mode 100644 index 0000000000..c09d2236e8 --- /dev/null +++ b/servers/slapd/back-sql/rdbms_depend/mssql/test_metadata.sql @@ -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 diff --git a/servers/slapd/back-sql/rdbms_depend/mysql/create.sql b/servers/slapd/back-sql/rdbms_depend/mysql/create.sql new file mode 100644 index 0000000000..1ff885a7ac --- /dev/null +++ b/servers/slapd/back-sql/rdbms_depend/mysql/create.sql @@ -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 + ); diff --git a/servers/slapd/back-sql/rdbms_depend/mysql/create_testdb.sql b/servers/slapd/back-sql/rdbms_depend/mysql/create_testdb.sql new file mode 100644 index 0000000000..c122ffae78 --- /dev/null +++ b/servers/slapd/back-sql/rdbms_depend/mysql/create_testdb.sql @@ -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 + ); + diff --git a/servers/slapd/back-sql/rdbms_depend/mysql/drop.sql b/servers/slapd/back-sql/rdbms_depend/mysql/drop.sql new file mode 100644 index 0000000000..95bd287eae --- /dev/null +++ b/servers/slapd/back-sql/rdbms_depend/mysql/drop.sql @@ -0,0 +1,5 @@ +DROP TABLE IF EXISTS ldap_attrs; + +DROP TABLE IF EXISTS ldap_entries; + +DROP TABLE IF EXISTS ldap_objclasses; diff --git a/servers/slapd/back-sql/rdbms_depend/mysql/drop_testdb.sql b/servers/slapd/back-sql/rdbms_depend/mysql/drop_testdb.sql new file mode 100644 index 0000000000..7c5e9e759e --- /dev/null +++ b/servers/slapd/back-sql/rdbms_depend/mysql/drop_testdb.sql @@ -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; diff --git a/servers/slapd/back-sql/rdbms_depend/mysql/slapd.conf b/servers/slapd/back-sql/rdbms_depend/mysql/slapd.conf new file mode 100644 index 0000000000..ba5a823216 --- /dev/null +++ b/servers/slapd/back-sql/rdbms_depend/mysql/slapd.conf @@ -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 (?,?,?,?)" diff --git a/servers/slapd/back-sql/rdbms_depend/mysql/test_data.sql b/servers/slapd/back-sql/rdbms_depend/mysql/test_data.sql new file mode 100644 index 0000000000..e436c5079d --- /dev/null +++ b/servers/slapd/back-sql/rdbms_depend/mysql/test_data.sql @@ -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); diff --git a/servers/slapd/back-sql/rdbms_depend/mysql/test_metadata.sql b/servers/slapd/back-sql/rdbms_depend/mysql/test_metadata.sql new file mode 100644 index 0000000000..735a26b79f --- /dev/null +++ b/servers/slapd/back-sql/rdbms_depend/mysql/test_metadata.sql @@ -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); diff --git a/servers/slapd/back-sql/rdbms_depend/oracle/create.sql b/servers/slapd/back-sql/rdbms_depend/oracle/create.sql new file mode 100644 index 0000000000..a5377200d3 --- /dev/null +++ b/servers/slapd/back-sql/rdbms_depend/oracle/create.sql @@ -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; diff --git a/servers/slapd/back-sql/rdbms_depend/oracle/create_testdb.sql b/servers/slapd/back-sql/rdbms_depend/oracle/create_testdb.sql new file mode 100644 index 0000000000..1fd3e11cc4 --- /dev/null +++ b/servers/slapd/back-sql/rdbms_depend/oracle/create_testdb.sql @@ -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; +/ + diff --git a/servers/slapd/back-sql/rdbms_depend/oracle/drop.sql b/servers/slapd/back-sql/rdbms_depend/oracle/drop.sql new file mode 100644 index 0000000000..d008937563 --- /dev/null +++ b/servers/slapd/back-sql/rdbms_depend/oracle/drop.sql @@ -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; + diff --git a/servers/slapd/back-sql/rdbms_depend/oracle/drop_testdb.sql b/servers/slapd/back-sql/rdbms_depend/oracle/drop_testdb.sql new file mode 100644 index 0000000000..0cf44637be --- /dev/null +++ b/servers/slapd/back-sql/rdbms_depend/oracle/drop_testdb.sql @@ -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; diff --git a/servers/slapd/back-sql/rdbms_depend/oracle/slapd.conf b/servers/slapd/back-sql/rdbms_depend/oracle/slapd.conf new file mode 100644 index 0000000000..4a40559cb3 --- /dev/null +++ b/servers/slapd/back-sql/rdbms_depend/oracle/slapd.conf @@ -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,?,?,?,?)" diff --git a/servers/slapd/back-sql/rdbms_depend/oracle/test_data.sql b/servers/slapd/back-sql/rdbms_depend/oracle/test_data.sql new file mode 100644 index 0000000000..33d6b9f4a2 --- /dev/null +++ b/servers/slapd/back-sql/rdbms_depend/oracle/test_data.sql @@ -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); diff --git a/servers/slapd/back-sql/rdbms_depend/oracle/test_metadata.sql b/servers/slapd/back-sql/rdbms_depend/oracle/test_metadata.sql new file mode 100644 index 0000000000..ad2e8b9727 --- /dev/null +++ b/servers/slapd/back-sql/rdbms_depend/oracle/test_metadata.sql @@ -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(?,?)}'); diff --git a/servers/slapd/back-sql/schema-map.c b/servers/slapd/back-sql/schema-map.c new file mode 100644 index 0000000000..78e4a74ace --- /dev/null +++ b/servers/slapd/back-sql/schema-map.c @@ -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 +#include +#include +#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; +} diff --git a/servers/slapd/back-sql/search.c b/servers/slapd/back-sql/search.c new file mode 100644 index 0000000000..fc4fa475aa --- /dev/null +++ b/servers/slapd/back-sql/search.c @@ -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 +#include +#include +#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;i0) + { + 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; +} diff --git a/servers/slapd/back-sql/sql-wrap.c b/servers/slapd/back-sql/sql-wrap.c new file mode 100644 index 0000000000..8ac653e8c3 --- /dev/null +++ b/servers/slapd/back-sql/sql-wrap.c @@ -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 +#include +#include +#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;incols;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; +} +