4 Copyright (C) Andrew Tridgell 2004
6 ** NOTE! The following LGPL license applies to the ldb
7 ** library. This does NOT imply that all of Samba is released
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.
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.
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
28 * Component: ldb tdb cache functions
30 * Description: cache special records in a ldb/tdb
32 * Author: Andrew Tridgell
36 #include "ldb/ldb_tdb/ldb_tdb.h"
39 initialise the baseinfo record
41 static int ltdb_baseinfo_init(struct ldb_context *ldb)
43 struct ltdb_private *ltdb = ldb->private_data;
44 struct ldb_message msg;
45 struct ldb_message_element el;
49 ltdb->sequence_number = 0;
53 msg.dn = ldb_strdup(ldb, LTDB_BASEINFO);
58 el.name = ldb_strdup(ldb, LTDB_SEQUENCE_NUMBER);
60 ldb_free(ldb, msg.dn);
67 val.data = ldb_strdup(ldb, "0");
69 ldb_free(ldb, el.name);
70 ldb_free(ldb, msg.dn);
76 ret = ltdb_store(ldb, &msg, TDB_INSERT);
78 ldb_free(ldb, msg.dn);
79 ldb_free(ldb, el.name);
80 ldb_free(ldb, val.data);
86 free any cache records
88 void ltdb_cache_free(struct ldb_context *ldb)
90 struct ltdb_private *ltdb = ldb->private_data;
91 struct ldb_alloc_ops alloc = ldb->alloc_ops;
92 ldb->alloc_ops.alloc = NULL;
94 ltdb->sequence_number = 0;
95 ltdb_search_dn1_free(ldb, <db->cache.baseinfo);
96 ltdb_search_dn1_free(ldb, <db->cache.indexlist);
97 ltdb_search_dn1_free(ldb, <db->cache.subclasses);
98 ltdb_search_dn1_free(ldb, <db->cache.attributes);
100 ldb_free(ldb, ltdb->cache.last_attribute.name);
101 memset(<db->cache, 0, sizeof(ltdb->cache));
103 ldb->alloc_ops = alloc;
107 load the cache records
109 int ltdb_cache_load(struct ldb_context *ldb)
111 struct ltdb_private *ltdb = ldb->private_data;
113 struct ldb_alloc_ops alloc = ldb->alloc_ops;
115 ldb->alloc_ops.alloc = NULL;
117 ltdb_search_dn1_free(ldb, <db->cache.baseinfo);
119 if (ltdb_search_dn1(ldb, LTDB_BASEINFO, <db->cache.baseinfo) == -1) {
123 /* possibly initialise the baseinfo */
124 if (!ltdb->cache.baseinfo.dn) {
125 if (ltdb_baseinfo_init(ldb) != 0) {
128 if (ltdb_search_dn1(ldb, LTDB_BASEINFO, <db->cache.baseinfo) != 1) {
133 /* if the current internal sequence number is the same as the one
134 in the database then assume the rest of the cache is OK */
135 seq = ldb_msg_find_double(<db->cache.baseinfo, LTDB_SEQUENCE_NUMBER, 0);
136 if (seq == ltdb->sequence_number) {
139 ltdb->sequence_number = seq;
141 ldb_free(ldb, ltdb->cache.last_attribute.name);
142 memset(<db->cache.last_attribute, 0, sizeof(ltdb->cache.last_attribute));
144 ltdb_search_dn1_free(ldb, <db->cache.indexlist);
145 ltdb_search_dn1_free(ldb, <db->cache.subclasses);
146 ltdb_search_dn1_free(ldb, <db->cache.attributes);
148 if (ltdb_search_dn1(ldb, LTDB_INDEXLIST, <db->cache.indexlist) == -1) {
151 if (ltdb_search_dn1(ldb, LTDB_SUBCLASSES, <db->cache.subclasses) == -1) {
154 if (ltdb_search_dn1(ldb, LTDB_ATTRIBUTES, <db->cache.attributes) == -1) {
159 ldb->alloc_ops = alloc;
163 ldb->alloc_ops = alloc;
169 increase the sequence number to indicate a database change
171 int ltdb_increase_sequence_number(struct ldb_context *ldb)
173 struct ltdb_private *ltdb = ldb->private_data;
174 struct ldb_message msg;
175 struct ldb_message_element el;
180 ldb_asprintf(ldb, &s, "%.0f", ltdb->sequence_number+1);
186 msg.num_elements = 1;
188 msg.dn = ldb_strdup(ldb, LTDB_BASEINFO);
189 el.name = ldb_strdup(ldb, LTDB_SEQUENCE_NUMBER);
192 el.flags = LDB_FLAG_MOD_REPLACE;
194 val.length = strlen(s);
196 ret = ltdb_modify_internal(ldb, &msg);
199 ldb_free(ldb, msg.dn);
200 ldb_free(ldb, el.name);
203 ltdb->sequence_number += 1;
211 return the attribute flags from the @ATTRIBUTES record
212 for the given attribute
214 int ltdb_attribute_flags(struct ldb_context *ldb, const char *attr_name)
216 struct ltdb_private *ltdb = ldb->private_data;
222 { "CASE_INSENSITIVE", LTDB_FLAG_CASE_INSENSITIVE },
223 { "INTEGER", LTDB_FLAG_INTEGER },
224 { "WILDCARD", LTDB_FLAG_WILDCARD },
230 if (ltdb->cache.last_attribute.name &&
231 ldb_attr_cmp(ltdb->cache.last_attribute.name, attr_name) == 0) {
232 return ltdb->cache.last_attribute.flags;
235 /* objectclass is a special default case */
236 if (ldb_attr_cmp(attr_name, LTDB_OBJECTCLASS) == 0) {
237 ret = LTDB_FLAG_OBJECTCLASS | LTDB_FLAG_CASE_INSENSITIVE;
240 attrs = ldb_msg_find_string(<db->cache.attributes, attr_name, NULL);
246 /* we avoid using strtok and friends due to their nasty
247 interface. This is a little trickier, but much nicer
248 from a C interface point of view */
249 while ((len = strcspn(attrs, " ,")) > 0) {
250 for (i=0;names[i].name;i++) {
251 if (strncmp(names[i].name, attrs, len) == 0 &&
252 names[i].name[len] == 0) {
253 ret |= names[i].value;
257 attrs += strspn(attrs, " ,");
260 if (ltdb->cache.last_attribute.name) ldb_free(ldb, ltdb->cache.last_attribute.name);
262 ltdb->cache.last_attribute.name = ldb_strdup(ldb, attr_name);
263 ltdb->cache.last_attribute.flags = ret;