r7133: work in progress, including a HIGHLY revised and simplified schema
[samba.git] / source / lib / ldb / ldb_sqlite3 / ldb_sqlite3.c
1 /* 
2    ldb database library
3    
4    Copyright (C) Andrew Tridgell  2004
5    
6    ** NOTE! The following LGPL license applies to the ldb
7    ** library. This does NOT imply that all of Samba is released
8    ** under the LGPL
9    
10    This library is free software; you can redistribute it and/or
11    modify it under the terms of the GNU Lesser General Public
12    License as published by the Free Software Foundation; either
13    version 2 of the License, or (at your option) any later version.
14    
15    This library is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    Lesser General Public License for more details.
19    
20    You should have received a copy of the GNU Lesser General Public
21    License along with this library; if not, write to the Free Software
22    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23 */
24
25 /*
26  *  Name: ldb
27  *
28  *  Component: ldb sqlite3 backend
29  *
30  *  Description: core files for SQLITE3 backend
31  *
32  *  Author: Derrell Lipman (based on Andrew Tridgell's LDAP backend)
33  */
34
35 #include "includes.h"
36 #include "ldb/include/ldb.h"
37 #include "ldb/include/ldb_private.h"
38 #include "ldb/ldb_sqlite3/ldb_sqlite3.h"
39
40 #undef SQL_EXEC                 /* just in case; not expected to be defined */
41 #define SQL_EXEC(lsqlite3, query, reset)                        \
42         do {                                                    \
43                 lsqlite3->last_rc =                             \
44                         sqlite3_step(lsqlite3->queries.query);  \
45                 if (lsqlite3->last_rc == SQLITE_BUSY || reset)  \
46                         (void) sqlite3_reset(lsqlite3->queries.query);  \
47         } while lsqlite3->last_rc == SQLITE_BUSY;
48
49
50
51 #if 0
52 /*
53  * we don't need this right now, but will once we add some backend options
54  *
55  * find an option in an option list (a null terminated list of strings)
56  *
57  * this assumes the list is short. If it ever gets long then we really should
58  * do this in some smarter way
59  */
60 static const char *
61 lsqlite3_option_find(const struct lsqlite3_private *lsqlite3,
62                      const char *name)
63 {
64         int                 i;
65         size_t              len = strlen(name);
66
67         if (!lsqlite3->options) return NULL;
68
69         for (i=0;lsqlite3->options[i];i++) {            
70                 if (strncmp(lsqlite3->options[i], name, len) == 0 &&
71                     lsqlite3->options[i][len] == '=') {
72                         return &lsqlite3->options[i][len+1];
73                 }
74         }
75
76         return NULL;
77 }
78 #endif
79
80 /*
81  * rename a record
82  */
83 static int
84 lsqlite3_rename(struct ldb_module *module,
85                 const char *olddn,
86                 const char *newdn)
87 {
88         int                         column;
89         struct lsqlite3_private *   lsqlite3 = module->private_data;
90
91         /* ignore ltdb specials */
92         if (olddn[0] == '@' ||newdn[0] == '@') {
93                 return 0;
94         }
95
96         /* Bind old distinguished names */
97         column = sqlite3_bind_parameter_index(lsqlite3->queries.renameDN,
98                                               ":oldDN");
99         if (sqlite3_bind_text(lsqlite3->queries.renameDN, column,
100                               olddn, strlen(olddn),
101                               SQLITE_STATIC) != SQLITE_OK) {
102                 return -1;
103         }
104
105         /* Bind new distinguished names */
106         column = sqlite3_bind_parameter_index(lsqlite3->queries.renameDN,
107                                               ":newDN");
108         if (sqlite3_bind_text(lsqlite3->queries.renameDN, column,
109                               newdn, strlen(newdn),
110                               SQLITE_STATIC) != SQLITE_OK) {
111                 return -1;
112         }
113
114         /* Execute the query.  This sets lsqlite3->last_rc */
115         SQL_EXEC(lsqlite3, renameDN, TRUE);
116
117         return lsqlite3->last_rc == 0 ? 0 : -1;
118 }
119
120 /*
121  * delete a record
122  */
123 static int
124 lsqlite3_delete(struct ldb_module *module,
125                 const char *dn)
126 {
127         int                         ret = 0;
128         int                         column;
129         struct lsqlite3_private *   lsqlite3 = module->private_data;
130
131         /* ignore ltdb specials */
132         if (dn[0] == '@') {
133                 return 0;
134         }
135         
136         /* Bind distinguished names */
137         column = sqlite3_bind_parameter_index(lsqlite3->queries.deleteDN,
138                                               ":dn");
139         if (sqlite3_bind_text(lsqlite3->queries.deleteDN, column,
140                               dn, strlen(dn),
141                               SQLITE_STATIC) != SQLITE_OK) {
142                 return -1;
143         }
144
145         /* Execute the query.  This sets lsqlite3->last_rc */
146         SQL_EXEC(lsqlite3, deleteDN, TRUE);
147
148         return lsqlite3->last_rc == 0 ? 0 : -1;
149 }
150
151 /*
152  * free a search result
153  */
154 static int
155 lsqlite3_search_free(struct ldb_module *module,
156                      struct ldb_message **res)
157 {
158         talloc_free(res);
159         return 0;
160 }
161
162
163 /*
164  * add a single set of ldap message values to a ldb_message
165  */
166 static int
167 lsqlite3_add_msg_attr(struct ldb_context *ldb,
168                       struct ldb_message *msg, 
169                       const char *attr,
170                       struct berval **bval)
171 {
172         int                          i;
173         int                          count;
174         struct ldb_message_element * el;
175
176         count = ldap_count_values_len(bval);
177
178         if (count <= 0) {
179                 return -1;
180         }
181
182         el = talloc_realloc(msg, msg->elements, struct ldb_message_element, 
183                               msg->num_elements + 1);
184         if (!el) {
185                 errno = ENOMEM;
186                 return -1;
187         }
188
189         msg->elements = el;
190
191         el = &msg->elements[msg->num_elements];
192
193         el->name = talloc_strdup(msg->elements, attr);
194         if (!el->name) {
195                 errno = ENOMEM;
196                 return -1;
197         }
198         el->flags = 0;
199
200         el->num_values = 0;
201         el->values = talloc_array(msg->elements, struct ldb_val, count);
202         if (!el->values) {
203                 errno = ENOMEM;
204                 return -1;
205         }
206
207         for (i=0;i<count;i++) {
208                 el->values[i].data = talloc_memdup(el->values, bval[i]->bv_val, bval[i]->bv_len);
209                 if (!el->values[i].data) {
210                         return -1;
211                 }
212                 el->values[i].length = bval[i]->bv_len;
213                 el->num_values++;
214         }
215
216         msg->num_elements++;
217
218         return 0;
219 }
220
221 /*
222  * search for matching records
223  */
224 static int
225 lsqlite3_search(struct ldb_module *module,
226                 const char *base,
227                 enum ldb_scope scope,
228                 const char *expression,
229                 const char * const *attrs,
230                 struct ldb_message ***res)
231 {
232         int                       count;
233         int                       msg_count;
234         struct ldb_context *      ldb = module->ldb;
235         struct lsqlite3_private * lsqlite3 = module->private_data;
236
237         if (base == NULL) {
238                 base = "";
239         }
240
241         lsqlite3->last_rc = ldap_search_s(lsqlite3->ldap, base, (int)scope, 
242                                       expression, 
243                                       discard_const_p(char *, attrs), 
244                                       0, &ldapres);
245         if (lsqlite3->last_rc != LDAP_SUCCESS) {
246                 return -1;
247         }
248
249         count = ldap_count_entries(lsqlite3->ldap, ldapres);
250         if (count == -1 || count == 0) {
251                 ldap_msgfree(ldapres);
252                 return count;
253         }
254
255         (*res) = talloc_array(lsqlite3, struct ldb_message *, count+1);
256         if (! *res) {
257                 ldap_msgfree(ldapres);
258                 errno = ENOMEM;
259                 return -1;
260         }
261
262         (*res)[0] = NULL;
263
264         msg_count = 0;
265
266         /* loop over all messages */
267         for (msg=ldap_first_entry(lsqlite3->ldap, ldapres); 
268              msg; 
269              msg=ldap_next_entry(lsqlite3->ldap, msg)) {
270                 BerElement *berptr = NULL;
271                 char *attr, *dn;
272
273                 if (msg_count == count) {
274                         /* hmm, got too many? */
275                         ldb_debug(ldb, LDB_DEBUG_FATAL, "Fatal: ldap message count inconsistent\n");
276                         break;
277                 }
278
279                 (*res)[msg_count] = talloc(*res, struct ldb_message);
280                 if (!(*res)[msg_count]) {
281                         goto failed;
282                 }
283                 (*res)[msg_count+1] = NULL;
284
285                 dn = ldap_get_dn(lsqlite3->ldap, msg);
286                 if (!dn) {
287                         goto failed;
288                 }
289
290                 (*res)[msg_count]->dn = talloc_strdup((*res)[msg_count], dn);
291                 ldap_memfree(dn);
292                 if (!(*res)[msg_count]->dn) {
293                         goto failed;
294                 }
295
296
297                 (*res)[msg_count]->num_elements = 0;
298                 (*res)[msg_count]->elements = NULL;
299                 (*res)[msg_count]->private_data = NULL;
300
301                 /* loop over all attributes */
302                 for (attr=ldap_first_attribute(lsqlite3->ldap, msg, &berptr);
303                      attr;
304                      attr=ldap_next_attribute(lsqlite3->ldap, msg, berptr)) {
305                         struct berval **bval;
306                         bval = ldap_get_values_len(lsqlite3->ldap, msg, attr);
307
308                         if (bval) {
309                                 lsqlite3_add_msg_attr(ldb, (*res)[msg_count], attr, bval);
310                                 ldap_value_free_len(bval);
311                         }                                         
312                         
313                         ldap_memfree(attr);
314                 }
315                 if (berptr) ber_free(berptr, 0);
316
317                 msg_count++;
318         }
319
320         ldap_msgfree(ldapres);
321
322         return msg_count;
323
324 failed:
325         if (*res) lsqlite3_search_free(module, *res);
326         return -1;
327 }
328
329
330 /*
331  * Issue a series of SQL statements to implement the ADD/MODIFY/DELETE
332  * requests in the ldb_message
333  */
334 static int
335 lsqlite3_msg_to_sql(struct ldb_context *ldb,
336                     const struct ldb_message *msg,
337                     long long dn_id,
338                     int use_flags)
339 {
340         int                         flags;
341         unsigned int                i;
342         unsigned int                j;
343         sqlite3_stmt *              stmt = NULL;
344         struct ldb_context *        ldb = module->ldb;
345         struct lsqlite3_private *   lsqlite3 = module->private_data;
346
347         for (i = 0; i < msg->num_elements; i++) {
348                 const struct ldb_message_element *el = &msg->elements[i];
349
350                 if (! use_flags) {
351                         flags = LDB_FLAG_MOD_ADD;
352                 } else {
353                         flags = el->flags & LDB_FLAG_MOD_MASK;
354                 }
355
356                 /* Determine which query to use */
357                 switch (flags) {
358                 case LDB_FLAG_MOD_ADD:
359                         stmt = lsqlite3->queries.addAttrValuePair;
360                         break;
361                         
362                 case LDB_FLAG_MOD_DELETE:
363                         stmt = lsqlite3->queries.deleteAttrValuePairs;
364                         break;
365
366                 case LDB_FLAG_MOD_REPLACE:
367                         stmt = lsqlite3->queries.replaceAttrValuePairs;
368                         break;
369                 }
370
371                 /*
372                  * All queries use dn id and attribute name.  Bind them now.
373                  */
374
375                 /* Bind distinguished name id */
376                 column =
377                         sqlite3_bind_parameter_index(
378                                 stmt,
379                                 ":dn_id");
380                 if (sqlite3_bind_int64(stmt,
381                                       column,
382                                       dn_id) != SQLITE_OK) {
383
384                         return -1;
385                 }
386
387                 /* Bind attribute name */
388                 column =
389                         sqlite3_bind_parameter_index(
390                                 stmt,
391                                 ":attr_name");
392                 if (sqlite3_bind_text(lsqlite3->queries.deleteDN, column,
393                                       el->name, strlen(el->name),
394                                       SQLITE_STATIC) != SQLITE_OK) {
395
396                         return -1;
397                 }
398
399
400                 /* For each value of the specified attribute name... */
401                 for (j = 0; j < el->num_values; j++) {
402
403                         /* ... bind the attribute value, if necessary */
404                         switch (flags) {
405                         case LDB_FLAG_MOD_ADD:
406                         case LDB_FLAG_MOD_REPLACE:
407                                 /* Bind attribute value */
408                                 column =
409                                         sqlite3_bind_parameter_index(
410                                                 stmt,
411                                                 ":attr_value");
412                                 if (sqlite3_bind_text(
413                                             stmt, column,
414                                             el->values[j].data,
415                                             el->values[j].length,
416                                             SQLITE_STATIC) != SQLITE_OK) {
417
418                                         return -1;
419                                 }
420
421                                 break;
422
423                         case LDB_FLAG_MOD_DELETE:
424                                 /* No additional parameters to this query */
425                                 break;
426                         }
427
428                         /* Execute the query */
429                         do {
430                                 lsqlite3->last_rc = sqlite3_step(stmt);
431                                 (void) sqlite3_reset(stmt);
432                         } while lsqlite3->last_rc == SQLITE_BUSY;
433
434                         /* Make sure we succeeded */
435                         if (lsqlite3->last_rc != SQLITE_OK) {
436                                 return -1;
437                         }
438                 }
439         }
440
441         return 0;
442 }
443
444
445 /*
446  * add a record
447  */
448 static int
449 lsqlite3_add(struct ldb_module *module,
450              const struct ldb_message *msg)
451 {
452         int                         ret;
453         struct ldb_context *        ldb = module->ldb;
454         struct lsqlite3_private *   lsqlite3 = module->private_data;
455
456         /* ignore ltdb specials */
457         if (msg->dn[0] == '@') {
458                 return 0;
459         }
460
461         /* Begin a transaction */
462         SQL_EXEC(lsqlite3, begin, TRUE);
463
464         /* This is a new DN.  Bind new distinguished name */
465         column = sqlite3_bind_parameter_index(lsqlite3->queries.newDN, ":dn");
466         if (sqlite3_bind_text(lsqlite3->queries.newDN, column,
467                               msg->dn, strlen(msg->dn),
468                               SQLITE_STATIC) != SQLITE_OK) {
469                 return -1;
470         }
471         
472         /* Add this new DN.  This sets lsqlite3->last_rc */
473         SQL_EXEC(lsqlite3, newDN, TRUE);
474         
475         if (lsqlite3->last_rc != SQLITE_DONE) {
476                 return -1;
477         }
478         
479         /* Get the id of the just-added DN */
480         dn_id = sqlite3_last_insert_rowid(lsqlite3->sqlite3);
481         
482         ret = lsqlite3_msg_to_sql(ldb, msg, dn_id, FALSE);
483
484         /* Did the attribute additions (if any) succeeded? */
485         if (ret == 0)
486         {
487                 /* Yup.  Commit the transaction */
488                 SQL_EXEC(lsqlite3, commit, TRUE);
489         }
490         else
491         {
492                 /* Attribute addition failed.  Rollback the transaction */
493                 SQL_EXEC(lsqlite3, rollback, TRUE);
494         }
495
496         /* If everything succeeded, return success */
497         return lsqlite3->last_rc == SQLITE_DONE && ret == 0 ? 0 : -1;
498 }
499
500
501 /*
502  * modify a record
503  */
504 static int
505 lsqlite3_modify(struct ldb_module *module,
506                 const struct ldb_message *msg)
507 {
508         int                         ret = 0;
509         struct ldb_context *        ldb = module->ldb;
510         struct lsqlite3_private *   lsqlite3 = module->private_data;
511
512         /* ignore ltdb specials */
513         if (msg->dn[0] == '@') {
514                 return 0;
515         }
516
517         /* Begin a transaction */
518         SQL_EXEC(lsqlite3, begin, TRUE);
519
520         /* Get the dn_id for the specified DN */
521         column =
522                 sqlite3_bind_parameter_index(
523                         lsqlite3->queries.getDNID,
524                         ":dn");
525         if (sqlite3_bind_text(lsqlite3->queries.getDNID,
526                               column,
527                               msg->dn, strlen(msg->dn),
528                               SQLITE_STATIC) != SQLITE_OK) {
529                 return -1;
530         }
531
532         /* Get the id of this DN.  This sets lsqlite3->last_rc */
533         SQL_EXEC(lsqlite3, getDNID, FALSE);
534                         
535         if (lsqlite3->last_rc != SQLITE_ROW) {
536                 return -1;
537         }
538
539         dn_id = sqlite3_column_int64(lsqlite3->queries.getDNID,
540                                      column);
541         (void) sqlite3_reset(lsqlite3->queries.getDNID);
542
543         ret = lsqlite3_msg_to_sql(ldb, msg, dn_id, FALSE);
544
545         /* Did the attribute additions (if any) succeeded? */
546         if (ret == 0)
547         {
548                 /* Yup.  Commit the transaction */
549                 SQL_EXEC(lsqlite3, commit, TRUE);
550         }
551         else
552         {
553                 /* Attribute addition failed.  Rollback the transaction */
554                 SQL_EXEC(lsqlite3, rollback, TRUE);
555         }
556
557         /* If everything succeeded, return success */
558         return lsqlite3->last_rc == SQLITE_DONE && ret == 0 ? 0 : -1;
559 }
560
561 static int
562 lsqlite3_lock(struct ldb_module *module,
563               const char *lockname)
564 {
565         int                         ret = 0;
566         struct ldb_context *        ldb = module->ldb;
567         struct lsqlite3_private *   lsqlite3 = module->private_data;
568
569         if (lockname == NULL) {
570                 return -1;
571         }
572
573         /* If we're already locked, just update lock count */
574         if (++lsqlite3->lock_count > 1) {
575                 return -1;
576         }
577             
578         /* Write-lock (but not read-lock) the database */
579         SQL_EXEC(lsqlite3, begin, TRUE);
580
581         return lsqlite3->last_rc == 0 ? 0 : -1;
582 }
583
584 static int
585 lsqlite3_unlock(struct ldb_module *module,
586                 const char *lockname)
587 {
588         int                         ret = 0;
589         struct ldb_context *        ldb = module->ldb;
590         struct lsqlite3_private *   lsqlite3 = module->private_data;
591
592         if (lockname == NULL) {
593                 return -1;
594         }
595
596         /* If we're not already locked, there's nothing to do */
597         if (lsqlite3->lock_count == 0) {
598                 return 0;
599         }
600
601         /* Decrement lock count */
602         if (--lsqlite3->lock_count == 0) {
603         
604                 /* Final unlock.  Unlock the database */
605                 SQL_EXEC(lsqlite3, commit, TRUE);
606         }
607
608         return lsqlite3->last_rc == 0 ? 0 : -1;
609 }
610
611 /*
612  * return extended error information
613  */
614 static const char *
615 lsqlite3_errstring(struct ldb_module *module)
616 {
617         struct lsqlite3_private *   lsqlite3 = module->private_data;
618
619         return sqlite3_errmsg(lsqlite3->sqlite3);
620 }
621
622
623 static const struct ldb_module_ops lsqlite3_ops = {
624         "sqlite",
625         lsqlite3_search,
626         lsqlite3_search_free,
627         lsqlite3_add,
628         lsqlite3_modify,
629         lsqlite3_delete,
630         lsqlite3_rename,
631         lsqlite3_lock,
632         lsqlite3_unlock,
633         lsqlite3_errstring
634 };
635
636
637 static int
638 lsqlite3_destructor(void *p)
639 {
640         struct lsqlite3_private *   lsqlite3 = p;
641
642         (void) sqlite3_close(lsqlite3->sqlite3);
643         return 0;
644 }
645
646 static int
647 lsqlite3_initialize(lsqlite3_private *lsqlite3,
648                     const char *url)
649 {
650         int             bNewDatabase = False;
651         char *          p;
652         char *          pTail;
653         struct stat     statbuf;
654         sqlite3_stmt *  stmt;
655         const char *    schema =       
656                 "
657                 -- ------------------------------------------------------
658
659                 PRAGMA auto_vacuum=1;
660
661                 -- ------------------------------------------------------
662
663                 BEGIN EXCLUSIVE;
664
665                 -- ------------------------------------------------------
666
667                 CREATE TABLE ldb_info AS 
668                   SELECT 'LDB' AS database_type, 
669                          '1.0' AS version;
670
671                 CREATE TABLE ldb_distinguished_names 
672                 (
673                   dn_id         INTEGER PRIMARY KEY AUTOINCREMENT, 
674                   dn            TEXT UNIQUE
675                 );
676
677                 CREATE TABLE ldb_object_classes 
678                 (
679                   class_name    TEXT PRIMARY KEY,
680                   tree_key      TEXT,
681                   max_child_num INTEGER
682                 );
683
684                 CREATE TABLE ldb_dn_object_classes 
685                 (
686                   dn_id         INTEGER REFERENCES ldb_distinguished_names, 
687                   class_name    TEXT REFERENCES ldb_object_classes 
688                 );
689
690                 CREATE TABLE ldb_attributes
691                 (
692                   attr_name             TEXT PRIMARY KEY,
693                   case_insensitive_p    BOOLEAN DEFAULT FALSE,
694                   wildcard_p            BOOLEAN DEFAULT FALSE,
695                   hidden_p              BOOLEAN DEFAULT FALSE,
696                   integer_p             BOOLEAN DEFAULT FALSE
697                 );
698
699                 CREATE TABLE ldb_attr_value_pairs 
700                 (
701                   dn_id         INTEGER REFERENCES ldb_distinguished_names, 
702                   attr_name     TEXT, -- optionally REFERENCES ldb_attributes
703                   attr_value    TEXT,
704
705                   UNIQUE (dn_id, attr_name, attr_value)
706                 );
707
708                 -- ------------------------------------------------------
709
710                 CREATE TRIGGER ldb_distinguished_names_delete_tr
711                   AFTER DELETE
712                   ON ldb_distinguished_names
713                   FOR EACH ROW
714                     BEGIN
715                       DELETE FROM ldb_attr_value_pairs
716                         WHERE dn_id = old.dn_id;
717                       DELETE FROM ldb_dn_object_classes
718                         WHERE dn_id = old.dn_id;
719                     END;
720
721                 CREATE TRIGGER ldb_attr_value_pairs_insert_tr
722                   BEFORE INSERT
723                   ON ldb_attr_value_pairs
724                   FOR EACH ROW
725                     BEGIN
726                       INSERT OR IGNORE INTO ldb_attributes
727                           (attr_name)
728                         VALUES
729                           (new.attr_name);
730                     END;
731
732                 CREATE TRIGGER ldb_attr_value_pairs_delete_tr
733                   AFTER DELETE
734                   ON ldb_attr_value_pairs
735                   FOR EACH ROW
736                     BEGIN
737                       DELETE FROM ldb_attributes
738                         WHERE (SELECT COUNT(*)
739                                  FROM ldb_attr_value_pairs
740                                  WHERE attr_name = old.attr_name) = 0
741                           AND attr_name = old.attr_name;
742                     END;
743
744                 -- ------------------------------------------------------
745
746                 CREATE INDEX ldb_distinguished_names_dn_idx
747                   ON ldb_distinguished_names (dn);
748
749                 CREATE INDEX ldb_object_classes_tree_key_idx
750                   ON ldb_object_classes (tree_key);
751
752
753                 CREATE INDEX ldb_dn_object_classes_dn_id_idx
754                   ON ldb_dn_object_classes (dn_id);
755
756                 CREATE INDEX ldb_dn_object_classes_class_name_idx
757                   ON ldb_dn_object_classes (class_name);
758
759
760                 CREATE INDEX ldb_attr_value_pairs_dn_id_name_case_idx
761                   ON ldb_attr_value_pairs (dn_id, attr_name);
762
763                 CREATE INDEX ldb_attr_value_pairs_dn_id_name_nocase_idx
764                   ON ldb_attr_value_pairs (dn_id, attr_name COLLATE NOCASE);
765
766                 -- ------------------------------------------------------
767
768                 /* all defaults for dn, initially */
769                 INSERT INTO ldb_attributes (attr_name)
770                   VALUES ('dn');
771
772                 /* We need an implicit 'top' level object class */
773                 INSERT INTO ldb_object_classes (class_name, tree_key)
774                   SELECT 'top', /* next_tree_key(NULL) */ '0001';
775
776                 -- ------------------------------------------------------
777
778                 COMMIT;
779
780                 -- ------------------------------------------------------
781                 ";
782
783         /* Skip protocol indicator of url  */
784         if ((p = strchr(url, ':')) == NULL) {
785                 return SQLITE_MISUSE;
786         } else {
787                 ++p;
788         }
789                 
790         /*
791          * See if we'll be creating a new database, or opening an existing one
792          */
793         if ((stat(p, &statbuf) < 0 && errno == ENOENT) ||
794             statbuf.st_size == 0) {
795
796                 bNewDatabase = True;
797         }
798
799         /* Try to open the (possibly empty/non-existent) database */
800         if ((lsqlite3->last_rc = sqlite3_open(p, &lsqlite3->sqlite3)) != SQLITE_SUCCESS) {
801                 return ret;
802         }
803
804         if (bNewDatabase) {
805                 /*
806                  * Create the database schema
807                  */
808                 for (pTail = schema; pTail != NULL; ) {
809
810                         if ((lsqlite3->last_rc = sqlite3_prepare(
811                                      lsqlite3->sqlite3,
812                                      pTail,
813                                      -1,
814                                      &stmt,
815                                      &pTail)) != SQLITE_SUCCESS ||
816                             (lsqlite3->last_rc = sqlite3_step(stmt)) != SQLITE_DONE ||
817                             (lsqlite3->last_rc = sqlite_finalize(stmt)) != SQLITE_SUCCESS) {
818
819                                 (void) sqlite3_close(lsqlite3->sqlite3);
820                                 return ret;
821                         }
822                 }
823         } else {
824                 /*
825                  * Ensure that the database we opened is one of ours
826                  */
827                 if ((lsqlite3->last_rc = sqlite3_prepare(
828                              lsqlite3->sqlite3,
829                              "SELECT COUNT(*) "
830                              "  FROM sqlite_master "
831                              "  WHERE type = 'table' "
832                              "    AND name IN "
833                              "      ("
834                              "        'ldb_info', "
835                              "        'ldb_distinguished_names', "
836                              "        'ldb_object_classes', "
837                              "        'ldb_dn_object_classes', "
838                              "        'ldb_attributes', "
839                              "        'ldb_attr_value_pairs' "
840                              "      );",
841                              -1,
842                              &stmt,
843                              &pTail)) != SQLITE_SUCCESS ||
844                     (lsqlite3->last_rc = sqlite3_step(stmt)) != SQLITE_ROW ||
845                     sqlite3_column_int(stmt, 0) != 6 ||
846                     (lsqlite3->last_rc = sqlite_finalize(stmt)) != SQLITE_SUCCESS ||
847
848                     (lsqlite3->last_rc = sqlite3_prepare(
849                              lsqlite3->sqlite3,
850                              "SELECT 1 "
851                              "  FROM ldb_info "
852                              "  WHERE database_type = 'LDB' "
853                              "    AND version = '1.0';",
854                              -1,
855                              &stmt,
856                              &pTail)) != SQLITE_SUCCESS ||
857                     (lsqlite3->last_rc = sqlite3_step(stmt)) != SQLITE_ROW ||
858                     (lsqlite3->last_rc = sqlite_finalize(stmt)) != SQLITE_SUCCESS) {
859                 
860                         /* It's not one that we created.  See ya! */
861                         (void) sqlite3_close(lsqlite3->sqlite3);
862                         return SQLITE_MISUSE;
863                 }
864         }
865
866         /*
867          * Pre-compile each of the queries we'll be using.
868          */
869
870         if ((lsqlite3->last_rc = sqlite3_prepare(
871                      lsqlite3->sqlite3,
872                      "BEGIN IMMEDIATE;",
873                      -1,
874                      &lsqlite3->queries.begin,
875                      &pTail)) != SQLITE_SUCCESS ||
876
877             (lsqlite3->last_rc = sqlite3_prepare(
878                      lsqlite3->sqlite3,
879                      "COMMIT;",
880                      -1,
881                      &lsqlite3->queries.commit,
882                      &pTail)) != SQLITE_SUCCESS ||
883
884             (lsqlite3->last_rc = sqlite3_prepare(
885                      lsqlite3->sqlite3,
886                      "ROLLBACK;",
887                      -1,
888                      &lsqlite3->queries.rollback,
889                      &pTail)) != SQLITE_SUCCESS ||
890
891             (lsqlite3->last_rc = sqlite3_prepare(
892                      lsqlite3->sqlite3,
893                      "INSERT INTO ldb_distinguished_names (dn_id, dn) "
894                      "  VALUES (:dn_id, :dn);",
895                      -1,
896                      &lsqlite3->queries.newDN,
897                      &pTail)) != SQLITE_SUCCESS ||
898
899             (lsqlite3->last_rc = sqlite3_prepare(
900                      lsqlite3->sqlite3,
901                      "UPDATE ldb_distinguished_names "
902                      "  SET dn = :newDN "
903                      "  WHERE dn = :oldDN;",
904                      -1,
905                      &lsqlite3->queries.renameDN,
906                      &pTail)) != SQLITE_SUCCESS ||
907
908             (lsqlite3->last_rc = sqlite3_prepare(
909                      lsqlite3->sqlite3,
910                      "DELETE FROM ldb_distinguished_names "
911                      "  WHERE dn = :dn;",
912                      -1,
913                      &lsqlite3->queries.deleteDN,
914                      &pTail)) != SQLITE_SUCCESS ||
915
916             (lsqlite3->last_rc = sqlite3_prepare(
917                      lsqlite3->sqlite3,
918                      "INSERT OR IGNORE INTO ldb_object_classes "
919                      "    (class_name, tree_key)"
920                      "  SELECT :class_name, next_tree_key(NULL);",
921                      -1,
922                      &lsqlite3->queries.newObjectClass,
923                      &pTail)) != SQLITE_SUCCESS ||
924             
925             (lsqlite3->last_rc = sqlite3_prepare(
926                      lsqlite3->sqlite3,
927                      "INSERT OR REPLACE INTO ldb_dn_object_classes "
928                      "    (dn_id, class_name) "
929                      "  VALUES (:dn_id, :class_name);",
930                      -1,
931                      &lsqlite3->queries.assignObjectClass,
932                      &pTail)) != SQLITE_SUCCESS ||
933             
934             (lsqlite3->last_rc = sqlite3_prepare(
935                      lsqlite3->sqlite3,
936                      "INSERT OR IGNORE INTO ldb_attributes (name) "
937                      "  VALUES (:name);",
938                      -1,
939                      &lsqlite3->queries.newAttributeUseDefaults,
940                      &pTail)) != SQLITE_SUCCESS ||
941             
942             (lsqlite3->last_rc = sqlite3_prepare(
943                      lsqlite3->sqlite3,
944                      "INSERT OR REPLACE INTO ldb_attributes "
945                      "    (name, "
946                      "     case_insensitive_p, "
947                      "     wildcard_p, "
948                      "     hidden_p, "
949                      "     integer_p) "
950                      "  VALUES (:name, "
951                      "          :case_insensitive_p, "
952                      "          :wildcard_p, "
953                      "          :hidden_p, "
954                      "          :integer_p);",
955                      -1,
956                      &lsqlite3->queries.newAttribute,
957                      &pTail)) != SQLITE_SUCCESS ||
958             
959             (lsqlite3->last_rc = sqlite3_prepare(
960                      lsqlite3->sqlite3,
961                      "INSERT INTO ldb_attr_value_pairs "
962                      "    (dn_id, attr_name, attr_value) "
963                      "  VALUES (:dn_id, :attr_name, :attr_value);",
964                      -1,
965                      &lsqlite3->queries.addAttrValuePair,
966                      &pTail)) != SQLITE_SUCCESS ||
967             
968             (lsqlite3->last_rc = sqlite3_prepare(
969                      lsqlite3->sqlite3,
970                      "UPDATE ldb_attr_value_pairs "
971                      "  SET attr_value = :attr_value "
972                      "  WHERE dn_id = :dn_id "
973                      "    AND attr_name = :attr_name;",
974                      -1,
975                      &lsqlite3->queries.addAttrValuePair,
976                      &pTail)) != SQLITE_SUCCESS ||
977             
978             (lsqlite3->last_rc = sqlite3_prepare(
979                      lsqlite3->sqlite3,
980                      "DELETE FROM ldb_attr_value_pairs "
981                      "  WHERE dn_id = :dn_id "
982                      "    AND attr_name = :attr_name;"
983                      -1,
984                      &lsqlite3->queries.deleteAttrValuePair,
985                      &pTail)) != SQLITE_SUCCESS ||
986             
987             (lsqlite3->last_rc = sqlite3_prepare(
988                      lsqlite3->sqlite3,
989                      "INSERT OR REPLACE INTO ldb_object_classes "
990                      "    (class_name, tree_key) "
991                      "  SELECT :child_class, next_tree_key(:parent_class);"
992                      -1,
993                      &lsqlite3->queries.insertSubclass,
994                      &pTail)) != SQLITE_SUCCESS ||
995
996             (lsqlite3->last_rc = sqlite3_prepare(
997                      lsqlite3->sqlite3,
998                      "SELECT dn_id "
999                      "  FROM ldb_distinguished_names "
1000                      "  WHERE dn = :dn;"
1001                      -1,
1002                      &lsqlite3->queries.getDNID,
1003                      &pTail)) != SQLITE_SUCCESS) {
1004
1005                 (void) sqlite3_close(lsqlite3->sqlite3);
1006                 return ret;
1007         }
1008
1009         return SQLITE_SUCCESS;
1010 }
1011
1012 /*
1013  * connect to the database
1014  */
1015 struct ldb_context *
1016 lsqlite3_connect(const char *url, 
1017                  unsigned int flags, 
1018                  const char *options[])
1019 {
1020         int                         i;
1021         struct ldb_context *        ldb = NULL;
1022         struct lsqlite3_private *   lsqlite3 = NULL;
1023
1024         ldb = talloc(NULL, struct ldb_context);
1025         if (!ldb) {
1026                 errno = ENOMEM;
1027                 goto failed;
1028         }
1029
1030         lsqlite3 = talloc(ldb, struct lsqlite3_private);
1031         if (!lsqlite3) {
1032                 errno = ENOMEM;
1033                 goto failed;
1034         }
1035
1036         lsqlite3->sqlite3 = NULL;
1037         lsqlite3->options = NULL;
1038         lsqlite3->lock_count = 0;
1039
1040         lsqlite3->last_rc = lsqlite3_initialize(&lsqlite3->sqlite3, url);
1041         if (lsqlite3->last_rc != SQLITE_SUCCESS) {
1042                 goto failed;
1043         }
1044
1045         talloc_set_destructor(lsqlite3, lsqlite3_destructor);
1046
1047         ldb->modules = talloc(ldb, struct ldb_module);
1048         if (!ldb->modules) {
1049                 errno = ENOMEM;
1050                 goto failed;
1051         }
1052         ldb->modules->ldb = ldb;
1053         ldb->modules->prev = ldb->modules->next = NULL;
1054         ldb->modules->private_data = lsqlite3;
1055         ldb->modules->ops = &lsqlite3_ops;
1056
1057         if (options) {
1058                 /*
1059                  * take a copy of the options array, so we don't have to rely
1060                  * on the caller keeping it around (it might be dynamic)
1061                  */
1062                 for (i=0;options[i];i++) ;
1063
1064                 lsqlite3->options = talloc_array(lsqlite3, char *, i+1);
1065                 if (!lsqlite3->options) {
1066                         goto failed;
1067                 }
1068                 
1069                 for (i=0;options[i];i++) {
1070
1071                         lsqlite3->options[i+1] = NULL;
1072                         lsqlite3->options[i] =
1073                                 talloc_strdup(lsqlite3->options, options[i]);
1074                         if (!lsqlite3->options[i]) {
1075                                 goto failed;
1076                         }
1077                 }
1078         }
1079
1080         return ldb;
1081
1082 failed:
1083         if (lsqlite3->sqlite3 != NULL) {
1084                 (void) sqlite3_close(lsqlite3->sqlite3);
1085         }
1086         talloc_free(ldb);
1087         return NULL;
1088 }
1089