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