s3: Fix some nonblank line endings
[kai/samba.git] / source3 / lib / dbwrap / dbwrap.c
1 /*
2    Unix SMB/CIFS implementation.
3    Database interface wrapper
4    Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2006
5
6    Major code contributions from Aleksey Fedoseev (fedoseev@ru.ibm.com)
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "dbwrap/dbwrap.h"
24 #include "dbwrap/dbwrap_private.h"
25 #include "util_tdb.h"
26
27 /*
28  * Fall back using fetch_locked if no genuine fetch operation is provided
29  */
30
31 NTSTATUS dbwrap_fallback_fetch(struct db_context *db, TALLOC_CTX *mem_ctx,
32                                TDB_DATA key, TDB_DATA *data)
33 {
34         struct db_record *rec;
35
36         rec = db->fetch_locked(db, mem_ctx, key);
37         if (rec == NULL) {
38                 return NT_STATUS_UNSUCCESSFUL;
39         }
40
41         data->dsize = rec->value.dsize;
42         data->dptr = talloc_move(mem_ctx, &rec->value.dptr);
43         TALLOC_FREE(rec);
44         return NT_STATUS_OK;
45 }
46
47 /*
48  * Fall back using fetch if no genuine exists operation is provided
49  */
50
51 static int dbwrap_fallback_exists(struct db_context *db, TDB_DATA key)
52 {
53         int res = dbwrap_parse_record(db, key, NULL, NULL);
54         return  ( res == -1) ? 0 : 1;
55 }
56
57 /*
58  * Fall back using fetch if no genuine parse operation is provided
59  */
60
61 int dbwrap_fallback_parse_record(struct db_context *db, TDB_DATA key,
62                                  int (*parser)(TDB_DATA key,
63                                                TDB_DATA data,
64                                                void *private_data),
65                                  void *private_data)
66 {
67         TDB_DATA data;
68         int res;
69         NTSTATUS status;
70
71         status = db->fetch(db, talloc_tos(), key, &data);
72         if (!NT_STATUS_IS_OK(status)) {
73                 return -1;
74         }
75
76         res = parser(key, data, private_data);
77         TALLOC_FREE(data.dptr);
78         return res;
79 }
80
81
82 static int delete_record(struct db_record *rec, void *data)
83 {
84         NTSTATUS status = rec->delete_rec(rec);
85         return NT_STATUS_IS_OK(status) ? 0 : -1;
86 }
87
88 /*
89  * Fallback wipe ipmlementation using traverse and delete if no genuine
90  * wipe operation is provided
91  */
92 int dbwrap_fallback_wipe(struct db_context *db)
93 {
94         NTSTATUS status = dbwrap_trans_traverse(db, &delete_record, NULL);
95         return NT_STATUS_IS_OK(status) ? 0 : -1;
96 }
97
98
99 /*
100  * Wrapper functions for the backend methods
101  */
102
103 TDB_DATA dbwrap_record_get_key(const struct db_record *rec)
104 {
105         return rec->key;
106 }
107
108 TDB_DATA dbwrap_record_get_value(const struct db_record *rec)
109 {
110         return rec->value;
111 }
112
113 NTSTATUS dbwrap_record_store(struct db_record *rec, TDB_DATA data, int flags)
114 {
115         return rec->store(rec, data, flags);
116 }
117
118 NTSTATUS dbwrap_record_delete(struct db_record *rec)
119 {
120         return rec->delete_rec(rec);
121 }
122
123 struct db_record *dbwrap_fetch_locked(struct db_context *db,
124                                       TALLOC_CTX *mem_ctx,
125                                       TDB_DATA key)
126 {
127         return db->fetch_locked(db, mem_ctx, key);
128 }
129
130 NTSTATUS dbwrap_fetch(struct db_context *db, TALLOC_CTX *mem_ctx,
131                       TDB_DATA key, TDB_DATA *value)
132 {
133         if (value == NULL) {
134                 return NT_STATUS_INVALID_PARAMETER;
135         }
136
137         return db->fetch(db, mem_ctx, key, value);
138 }
139
140 bool dbwrap_exists(struct db_context *db, TDB_DATA key)
141 {
142         int result;
143         if (db->exists != NULL) {
144                 result = db->exists(db, key);
145         } else {
146                 result = dbwrap_fallback_exists(db,key);
147         }
148         return (result == 1);
149 }
150
151 NTSTATUS dbwrap_store(struct db_context *db, TDB_DATA key,
152                       TDB_DATA data, int flags)
153 {
154         struct db_record *rec;
155         NTSTATUS status;
156
157         rec = db->fetch_locked(db, talloc_tos(), key);
158         if (rec == NULL) {
159                 return NT_STATUS_NO_MEMORY;
160         }
161
162         status = rec->store(rec, data, flags);
163         TALLOC_FREE(rec);
164         return status;
165 }
166
167 NTSTATUS dbwrap_delete(struct db_context *db, TDB_DATA key)
168 {
169         struct db_record *rec;
170         NTSTATUS status;
171
172         rec = db->fetch_locked(db, talloc_tos(), key);
173         if (rec == NULL) {
174                 return NT_STATUS_NO_MEMORY;
175         }
176         status = rec->delete_rec(rec);
177         TALLOC_FREE(rec);
178         return status;
179 }
180
181 NTSTATUS dbwrap_traverse(struct db_context *db,
182                          int (*f)(struct db_record*, void*),
183                          void *private_data,
184                          int *count)
185 {
186         int ret = db->traverse(db, f, private_data);
187
188         if (ret < 0) {
189                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
190         }
191
192         if (count != NULL) {
193                 *count = ret;
194         }
195
196         return NT_STATUS_OK;
197 }
198
199 NTSTATUS dbwrap_traverse_read(struct db_context *db,
200                               int (*f)(struct db_record*, void*),
201                               void *private_data,
202                               int *count)
203 {
204         int ret = db->traverse_read(db, f, private_data);
205
206         if (ret < 0) {
207                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
208         }
209
210         if (count != NULL) {
211                 *count = ret;
212         }
213
214         return NT_STATUS_OK;
215 }
216
217 static int dbwrap_null_parser(TDB_DATA key, TDB_DATA val, void* data)
218 {
219         return 0;
220 }
221
222 int dbwrap_parse_record(struct db_context *db, TDB_DATA key,
223                         int (*parser)(TDB_DATA key, TDB_DATA data,
224                                       void *private_data),
225                         void *private_data)
226 {
227         if (parser == NULL) {
228                 parser = dbwrap_null_parser;
229         }
230
231         if (db->parse_record) {
232                 return db->parse_record(db, key, parser, private_data);
233         } else {
234                 return dbwrap_fallback_parse_record(db, key, parser, private_data);
235         }
236 }
237
238 int dbwrap_wipe(struct db_context *db)
239 {
240         return db->wipe(db);
241 }
242
243 int dbwrap_get_seqnum(struct db_context *db)
244 {
245         return db->get_seqnum(db);
246 }
247
248 int dbwrap_get_flags(struct db_context *db)
249 {
250         return db->get_flags(db);
251 }
252
253 int dbwrap_transaction_start(struct db_context *db)
254 {
255         return db->transaction_start(db);
256 }
257
258 int dbwrap_transaction_commit(struct db_context *db)
259 {
260         return db->transaction_commit(db);
261 }
262
263 int dbwrap_transaction_cancel(struct db_context *db)
264 {
265         return db->transaction_cancel(db);
266 }