]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ndb/config.cpp
MySQL NDB Cluster backend (experimental)
[openldap] / servers / slapd / back-ndb / config.cpp
1 /* config.cpp - ndb backend configuration file routine */
2 /* $OpenLDAP$ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4  *
5  * Copyright 2008 The OpenLDAP Foundation.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted only as authorized by the OpenLDAP
10  * Public License.
11  *
12  * A copy of this license is available in the file LICENSE in the
13  * top-level directory of the distribution or, alternatively, at
14  * <http://www.OpenLDAP.org/license.html>.
15  */
16 /* ACKNOWLEDGEMENTS:
17  * This work was initially developed by Howard Chu for inclusion
18  * in OpenLDAP Software. This work was sponsored by MySQL.
19  */
20
21 #include "portable.h"
22 #include "lutil.h"
23
24 #include "back-ndb.h"
25
26 #include "config.h"
27
28 extern "C" {
29         static ConfigDriver ndb_cf_gen;
30 };
31
32 enum {
33         NDB_ATLEN = 1,
34         NDB_ATSET,
35         NDB_INDEX
36 };
37
38 static ConfigTable ndbcfg[] = {
39         { "dbhost", "hostname", 2, 2, 0, ARG_STRING|ARG_OFFSET,
40                 (void *)offsetof(struct ndb_info, ni_hostname),
41                 "( OLcfgDbAt:6.1 NAME 'olcDbHost' "
42                         "DESC 'Hostname of SQL server' "
43                         "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
44         { "dbname", "name", 2, 2, 0, ARG_STRING|ARG_OFFSET,
45                 (void *)offsetof(struct ndb_info, ni_dbname),
46                 "( OLcfgDbAt:6.2 NAME 'olcDbName' "
47                         "DESC 'Name of SQL database' "
48                         "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
49         { "dbuser", "username", 2, 2, 0, ARG_STRING|ARG_OFFSET,
50                 (void *)offsetof(struct ndb_info, ni_username),
51                 "( OLcfgDbAt:6.3 NAME 'olcDbUser' "
52                         "DESC 'Username for SQL session' "
53                         "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
54         { "dbpass", "password", 2, 2, 0, ARG_STRING|ARG_OFFSET,
55                 (void *)offsetof(struct ndb_info, ni_password),
56                 "( OLcfgDbAt:6.4 NAME 'olcDbPass' "
57                         "DESC 'Password for SQL session' "
58                         "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
59         { "dbport", "port", 2, 2, 0, ARG_UINT|ARG_OFFSET,
60                 (void *)offsetof(struct ndb_info, ni_port),
61                 "( OLcfgDbAt:6.5 NAME 'olcDbPort' "
62                         "DESC 'Port number of SQL server' "
63                         "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
64         { "dbsocket", "path", 2, 2, 0, ARG_STRING|ARG_OFFSET,
65                 (void *)offsetof(struct ndb_info, ni_socket),
66                 "( OLcfgDbAt:6.6 NAME 'olcDbSocket' "
67                         "DESC 'Local socket path of SQL server' "
68                         "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
69         { "dbflag", "flag", 2, 2, 0, ARG_LONG|ARG_OFFSET,
70                 (void *)offsetof(struct ndb_info, ni_clflag),
71                 "( OLcfgDbAt:6.7 NAME 'olcDbFlag' "
72                         "DESC 'Flags for SQL session' "
73                         "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
74         { "dbconnect", "hostname", 2, 2, 0, ARG_STRING|ARG_OFFSET,
75                 (void *)offsetof(struct ndb_info, ni_connectstr),
76                 "( OLcfgDbAt:6.8 NAME 'olcDbConnect' "
77                         "DESC 'Hostname of NDB server' "
78                         "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
79         { "dbconnections", "number", 2, 2, 0, ARG_INT|ARG_OFFSET,
80                 (void *)offsetof(struct ndb_info, ni_nconns),
81                 "( OLcfgDbAt:6.9 NAME 'olcDbConnections' "
82                         "DESC 'Number of cluster connections to open' "
83                         "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
84         { "attrlen", "attr> <len", 3, 3, 0, ARG_MAGIC|NDB_ATLEN,
85                 (void *)ndb_cf_gen,
86                 "( OLcfgDbAt:6.10 NAME 'olcNdbAttrLen' "
87                         "DESC 'Column length of a specific attribute' "
88                         "EQUALITY caseIgnoreMatch "
89                         "SYNTAX OMsDirectoryString )", NULL, NULL },
90         { "attrset", "set> <attrs", 3, 3, 0, ARG_MAGIC|NDB_ATSET,
91                 (void *)ndb_cf_gen,
92                 "( OLcfgDbAt:6.11 NAME 'olcNdbAttrSet' "
93                         "DESC 'Set of common attributes' "
94                         "EQUALITY caseIgnoreMatch "
95                         "SYNTAX OMsDirectoryString )", NULL, NULL },
96         { "index", "attr", 2, 2, 0, ARG_MAGIC|NDB_INDEX,
97                 (void *)ndb_cf_gen, "( OLcfgDbAt:0.2 NAME 'olcDbIndex' "
98                 "DESC 'Attribute to index' "
99                 "EQUALITY caseIgnoreMatch "
100                 "SYNTAX OMsDirectoryString )", NULL, NULL },
101         { NULL, NULL, 0, 0, 0, ARG_IGNORED,
102                 NULL, NULL, NULL, NULL }
103 };
104
105 static ConfigOCs ndbocs[] = {
106         {
107                 "( OLcfgDbOc:6.2 "
108                 "NAME 'olcNdbConfig' "
109                 "DESC 'NDB backend configuration' "
110                 "SUP olcDatabaseConfig "
111                 "MUST ( olcDbHost $ olcDbName $ olcDbConnect ) "
112                 "MAY ( olcDbUser $ olcDbPass $ olcDbPort $ olcDbSocket $ "
113                 "olcDbFlag $ olcDbConnections $ olcNdbAttrLen $ "
114                 "olcDbIndex $ olcNdbAttrSet ) )",
115                         Cft_Database, ndbcfg },
116         { NULL, Cft_Abstract, NULL }
117 };
118
119 static int
120 ndb_cf_gen( ConfigArgs *c )
121 {
122         struct ndb_info *ni = (struct ndb_info *)c->be->be_private;
123         int i, rc;
124         NdbAttrInfo *ai;
125         NdbOcInfo *oci;
126         ListNode *ln, **l2;
127         struct berval bv, *bva;
128
129         if ( c->op == SLAP_CONFIG_EMIT ) {
130                 char buf[BUFSIZ];
131                 rc = 0;
132                 bv.bv_val = buf;
133                 switch( c->type ) {
134                 case NDB_ATLEN:
135                         if ( ni->ni_attrlens ) {
136                                 for ( ln = ni->ni_attrlens; ln; ln=ln->ln_next ) {
137                                         ai = (NdbAttrInfo *)ln->ln_data;
138                                         bv.bv_len = snprintf( buf, sizeof(buf),
139                                                 "%s %d", ai->na_name.bv_val,
140                                                         ai->na_len );
141                                         value_add_one( &c->rvalue_vals, &bv );
142                                 }
143                         } else {
144                                 rc = 1;
145                         }
146                         break;
147
148                 case NDB_ATSET:
149                         if ( ni->ni_attrsets ) {
150                                 char *ptr, *end = buf+sizeof(buf);
151                                 for ( ln = ni->ni_attrsets; ln; ln=ln->ln_next ) {
152                                         oci = (NdbOcInfo *)ln->ln_data;
153                                         ptr = lutil_strcopy( buf, oci->no_name.bv_val );
154                                         *ptr++ = ' ';
155                                         for ( i=0; i<oci->no_nattrs; i++ ) {
156                                                 if ( end - ptr < oci->no_attrs[i]->na_name.bv_len+1 )
157                                                         break;
158                                                 if ( i )
159                                                         *ptr++ = ',';
160                                                 ptr = lutil_strcopy(ptr,
161                                                         oci->no_attrs[i]->na_name.bv_val );
162                                         }
163                                         bv.bv_len = ptr - buf;
164                                         value_add_one( &c->rvalue_vals, &bv );
165                                 }
166                         } else {
167                                 rc = 1;
168                         }
169                         break;
170
171                 case NDB_INDEX:
172                         if ( ni->ni_attridxs ) {
173                                 for ( ln = ni->ni_attridxs; ln; ln=ln->ln_next ) {
174                                         ai = (NdbAttrInfo *)ln->ln_data;
175                                         value_add_one( &c->rvalue_vals, &ai->na_name );
176                                 }
177                         } else {
178                                 rc = 1;
179                         }
180                         break;
181
182                 }
183                 return rc;
184         } else if ( c->op == LDAP_MOD_DELETE ) { /* FIXME */
185                 rc = 0;
186                 switch( c->type ) {
187                 case NDB_INDEX:
188                         if ( c->valx == -1 ) {
189                                 int i;
190
191                                 /* delete all */
192
193                         } else {
194
195                         }
196                         break;
197                 }
198                 return rc;
199         }
200
201         switch( c->type ) {
202         case NDB_ATLEN:
203                 ber_str2bv( c->argv[1], 0, 0, &bv );
204                 ai = ndb_ai_get( ni, &bv );
205                 if ( !ai ) {
206                         snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: invalid attr %s",
207                                 c->log, c->argv[1] );
208                         Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 );
209                         return -1;
210                 }
211                 for ( ln = ni->ni_attrlens; ln; ln = ln->ln_next ) {
212                         if ( ln->ln_data == (void *)ai ) {
213                                 snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: attr len already set for %s",
214                                         c->log, c->argv[1] );
215                                 Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 );
216                                 return -1;
217                         }
218                 }
219                 ai->na_len = atoi( c->argv[2] );
220                 ai->na_flag |= NDB_INFO_ATLEN;
221                 ln = (ListNode *)ch_malloc( sizeof(ListNode));
222                 ln->ln_data = ai;
223                 ln->ln_next = NULL;
224                 for ( l2 = &ni->ni_attrlens; *l2; l2 = &(*l2)->ln_next );
225                 *l2 = ln;
226                 break;
227                 
228         case NDB_INDEX:
229                 ber_str2bv( c->argv[1], 0, 0, &bv );
230                 ai = ndb_ai_get( ni, &bv );
231                 if ( !ai ) {
232                         snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: invalid attr %s",
233                                 c->log, c->argv[1] );
234                         Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 );
235                         return -1;
236                 }
237                 for ( ln = ni->ni_attridxs; ln; ln = ln->ln_next ) {
238                         if ( ln->ln_data == (void *)ai ) {
239                                 snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: attr index already set for %s",
240                                         c->log, c->argv[1] );
241                                 Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 );
242                                 return -1;
243                         }
244                 }
245                 ai->na_flag |= NDB_INFO_INDEX;
246                 ln = (ListNode *)ch_malloc( sizeof(ListNode));
247                 ln->ln_data = ai;
248                 ln->ln_next = NULL;
249                 for ( l2 = &ni->ni_attridxs; *l2; l2 = &(*l2)->ln_next );
250                 *l2 = ln;
251                 break;
252
253         case NDB_ATSET:
254                 ber_str2bv( c->argv[1], 0, 0, &bv );
255                 bva = ndb_str2bvarray( c->argv[2], strlen( c->argv[2] ), ',' );
256                 rc = ndb_aset_get( ni, &bv, bva, &oci );
257                 ch_free( bva );
258                 if ( rc ) {
259                         if ( rc == LDAP_ALREADY_EXISTS ) {
260                                 snprintf( c->cr_msg, sizeof( c->cr_msg ),
261                                         "%s: attrset %s already defined",
262                                         c->log, c->argv[1] );
263                         } else {
264                                 snprintf( c->cr_msg, sizeof( c->cr_msg ),
265                                         "%s: invalid attrset %s (%d)",
266                                         c->log, c->argv[1], rc );
267                         }
268                         Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 );
269                         return -1;
270                 }
271                 ln = (ListNode *)ch_malloc( sizeof(ListNode));
272                 ln->ln_data = oci;
273                 ln->ln_next = NULL;
274                 for ( l2 = &ni->ni_attrsets; *l2; l2 = &(*l2)->ln_next );
275                 *l2 = ln;
276                 break;
277         }
278         return 0;
279 }
280
281 extern "C"
282 int ndb_back_init_cf( BackendInfo *bi )
283 {
284         bi->bi_cf_ocs = ndbocs;
285
286         return config_register_schema( ndbcfg, ndbocs );
287 }