1 /* 2 Copyright (C) 2015-2021, Dirk Krause 3 SPDX-License-Identifier: BSD-3-Clause 4 */ 5 6 /* 7 WARNING: This file was generated by the dkct program (see 8 http://dktools.sourceforge.net/ for details). 9 Changes you make here will be lost if dkct is run again! 10 You should modify the original source and run dkct on it. 11 Original source: dk4dbi.ctr 12 */ 13 14 #ifndef DK4DBI_H_INCLUDED 15 /** Avoid multiple inclusions. */ 16 #define DK4DBI_H_INCLUDED 1 17 18 19 /** @file dk4dbi.h Interface to databases. 20 */ 21 22 #ifndef DK4CONF_H_INCLUDED 23 #if DK4_BUILDING_DKTOOLS4 24 #include "dk4conf.h" 25 #else 26 #include <dktools-4/dk4conf.h> 27 #endif 28 #endif 29 30 #ifndef DK4TYPES_H_INCLUDED 31 #if DK4_BUILDING_DKTOOLS4 32 #include <libdk4base/dk4types.h> 33 #else 34 #include <dktools-4/dk4types.h> 35 #endif 36 #endif 37 38 #if DK4_HAVE_UNISTD_H 39 #ifndef UNISTD_H_INCLUDED 40 #include <unistd.h> 41 #define UNISTD_H_INCLUDED 1 42 #endif 43 #endif 44 45 #if DK4_HAVE_SYS_TYPES_H 46 #ifndef SYS_TYPES_H_INCLUDED 47 #include <sys/types.h> 48 #define SYS_TYPES_H_INCLUDED 1 49 #endif 50 #endif 51 52 #if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1) 53 #include <db.h> 54 #endif 55 56 #if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1) 57 #if DK4_HAVE_FCNTL_H 58 #ifndef FCNTL_H_INCLUDED 59 #include <fcntl.h> 60 #define FCNTL_H_INCLUDED 1 61 #endif 62 #endif 63 #ifndef NDBM_H_INCLUDED 64 #include <ndbm.h> 65 #define NDBM_H_INCLUDED 1 66 #endif 67 #endif 68 69 #ifndef DK4TYPES_H_INCLUDED 70 #if DK4_BUILDING_DKTOOLS4 71 #include <libdk4base/dk4types.h> 72 #else 73 #include <dktools-4/dk4types.h> 74 #endif 75 #endif 76 77 #ifndef DK4ERROR_H_INCLUDED 78 #if DK4_BUILDING_DKTOOLS4 79 #include <libdk4base/dk4error.h> 80 #else 81 #include <dktools-4/dk4error.h> 82 #endif 83 #endif 84 85 #ifndef DK4STO_H_INCLUDED 86 #if DK4_BUILDING_DKTOOLS4 87 #include <libdk4c/dk4sto.h> 88 #else 89 #include <dktools-4/dk4sto.h> 90 #endif 91 #endif 92 93 94 95 /** Backend types. 96 */ 97 enum { 98 /** No backend specified yet. 99 */ 100 DK4_DB_BE_UNKNOWN = -1 , 101 102 /** In-memory database. 103 */ 104 DK4_DB_BE_MEMORY = 0 , 105 106 /** Berkeley DB. 107 */ 108 DK4_DB_BE_BDB = 1 , 109 110 /** NDBM. 111 */ 112 DK4_DB_BE_NDBM = 2 113 }; 114 115 116 117 /** Options. 118 */ 119 enum { 120 /** Reset key data before releasing 121 memory. 122 */ 123 DK4_DB_OPT_RESET_KEY = 1 , 124 125 /** Reset value data before releasing 126 memory. 127 */ 128 DK4_DB_OPT_RESET_VALUE = 2 , 129 }; 130 131 132 133 /** Details for an in-memory database. 134 */ 135 typedef struct { 136 dk4_sto_t *s; /**< Storage container. */ 137 dk4_sto_it_t *i; /**< Storage iterator. */ 138 } dk4_dbi_mem_t; 139 140 141 #if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1) 142 /** Details for a Berkeley DB database. 143 */ 144 typedef struct { 145 DB *db; /**< DB structure. */ 146 } dk4_dbi_bdb_t; 147 #endif 148 149 #if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1) 150 /** Details for an NDBM database. 151 */ 152 typedef struct { 153 DBM *dbm; /**< NDBM structure. */ 154 } dk4_dbi_ndbm_t; 155 #endif 156 157 /** Details for one backend. 158 */ 159 typedef union { 160 dk4_dbi_mem_t mem; /**< Details for in-memory database. */ 161 #if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1) 162 dk4_dbi_bdb_t bdb; /**< Details for Berkeley DB. */ 163 #endif 164 #if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1) 165 dk4_dbi_ndbm_t ndbm; /**< Details for NDBM. */ 166 #endif 167 int dummy; /**< Just to have a second component. */ 168 } dk4_dbi_det_t; 169 170 /** Database structure. 171 */ 172 typedef struct { 173 dk4_dbi_det_t dt; /**< Backend-specific details. */ 174 dkChar *fn; /**< File name. */ 175 size_t km; /**< Maximum key size. */ 176 size_t vm; /**< Maximum value size. */ 177 int tp; /**< Backend type. */ 178 int op; /**< Options. */ 179 int wa; /**< Flag: Write access. */ 180 int uc; /**< Flag: Have unsynchronized changes. */ 181 } dk4_dbi_t; 182 183 /** Function to traverse a simple database. 184 The function must check the kb, ks, vb and vs arguments 185 for validity, they are passed as found by the backend 186 functions (this means pointers may be NULL, sizes may be 0). 187 @param Object modified during traversal, may be NULL. 188 @param kb Key data. 189 @param ks Key size. 190 @param vb Value data. 191 @param vs Value size. 192 @return 1 on success, 0 on error (can continue), -1 on error (abort). 193 */ 194 typedef 195 int 196 dk4dbi_traverse_fct_t( 197 void *obj, 198 const void *kb, 199 size_t ks, 200 const void *vb, 201 size_t vs 202 ); 203 204 205 #ifdef __cplusplus 206 extern "C" { 207 #endif 208 209 /** Open database. 210 @param fn File name. 211 @param tp Backend type. 212 @param wa Flag: Write access required. 213 @param tr Flag: Truncate existing database 214 (only in conjunction with wa). 215 @param km Maximum key size (0 for unlimited). 216 @param vm Maximum value size (0 for unlimited). 217 The limits are used on all backends for writing, 218 on in-memory databases also for reading. 219 @param erp Error report, may be NULL. 220 @return Pointer to new database structure on success, NULL on error. 221 222 Error codes: 223 - DK4_E_INVALID_ARGUMENTS<br> 224 if fn is NULL or tp contains an invalid type number, 225 - DK4_E_NOT_SUPPORTED<br> 226 if the database type is not supported, 227 - DK4_E_MATH_OVERFLOW<br> 228 on numeric overflow when calculating size, 229 - DK4_E_MEMORY_ALLOCATION_FAILED<br> 230 with mem.elsize and mem.nelem 231 set if there is not enough memory available, 232 - DK4_E_SYNTAX<br> 233 if 234 - the database file name does not refer to a regular file 235 - or the file contents is not an in-memory database 236 - or key/value sizes in the file are in conflict with restrictions, 237 - DK4_E_SEC_CHECK<br> 238 with failed check id in iDetails1 if access is denied by additional 239 security checks, 240 - DK4_E_MEMORY_ALLOCATION_FAILED<br> 241 with mem.elsize and mem.nelem 242 set if there is not enough memory available, 243 - DK4_E_OPEN_READ_FAILED<br> 244 if fopen() or fread() failed, 245 - DK4_E_OPEN_WRITE_FAILED<br> 246 if fopen() or fwrite() failed, 247 - DK4_E_CLOSE_FAILED<br> 248 with errno value in iDetails1 if fclose() failed. 249 250 */ 251 dk4_dbi_t * 252 dk4dbi_open_with_type( 253 const dkChar *fn, 254 int tp, 255 int wa, 256 int tr, 257 size_t km, 258 size_t vm, 259 dk4_er_t *erp 260 ); 261 262 /** Open database. 263 @param fn Database type and file name. 264 The database type is one from "mem", "bdb" or "ndbm". 265 Database type and file name are separated by two 266 colons "::". 267 @param wa Flag: Write access required. 268 @param tr Flag: Truncate existing database 269 (only in conjunction with wa). 270 @param km Maximum key size (0 for unlimited). 271 @param vm Maximum value size (0 for unlimited). 272 @param erp Error report, may be NULL. 273 @return Pointer to new database structure on success, NULL on error. 274 275 Error codes: 276 - DK4_E_INVALID_ARGUMENTS<br> 277 if fn is NULL or tp contains an invalid type number, 278 - DK4_E_NOT_SUPPORTED<br> 279 if the database type is not supported, 280 - DK4_E_MATH_OVERFLOW<br> 281 on numeric overflow when calculating size, 282 - DK4_E_MEMORY_ALLOCATION_FAILED<br> 283 with mem.elsize and mem.nelem 284 set if there is not enough memory available, 285 - DK4_E_SYNTAX<br> 286 if 287 - the specification contains an invalid backend type 288 - the database file name does not refer to a regular file 289 - or the file contents is not an in-memory database 290 - or key/value sizes in the file are in conflict with restrictions 291 - or an invalid database type was specified, 292 - DK4_E_SEC_CHECK<br> 293 with failed check id in iDetails1 if access is denied by additional 294 security checks, 295 - DK4_E_MEMORY_ALLOCATION_FAILED<br> 296 with mem.elsize and mem.nelem 297 set if there is not enough memory available, 298 - DK4_E_OPEN_READ_FAILED<br> 299 if fopen() or fread() failed, 300 - DK4_E_OPEN_WRITE_FAILED<br> 301 if fopen() or fwrite() failed, 302 - DK4_E_CLOSE_FAILED<br> 303 with errno value in iDetails1 if fclose() failed. 304 */ 305 dk4_dbi_t * 306 dk4dbi_open( 307 const dkChar *fn, 308 int wa, 309 int tr, 310 size_t km, 311 size_t vm, 312 dk4_er_t *erp 313 ); 314 315 /** Find file name part from combined type/name. 316 @param filename Combined database type and file name. 317 @return Valid pointer to file name part on success, NULL on error. 318 */ 319 const dkChar * 320 dk4dbi_filename_part(const dkChar *filename); 321 322 /** Close database, release resources. 323 @param db Database to close. 324 @param erp Error report, may be NULL. 325 @return 1 on success, 0 on error. 326 327 Error codes: 328 - DK4_E_INVALID_ARGUMENTS<br> 329 if db is NULL, 330 - DK4_E_NOT_SUPPORTED<br> 331 if db indicates an unsupported backend type, 332 - DK4_E_SYNTAX<br> 333 if the database file name does not refer to a regular file, 334 - DK4_E_SEC_CHECK<br> 335 with failed check id in iDetails1 if access is denied by additional 336 security checks, 337 - DK4_E_OPEN_WRITE_FAILED<br> 338 with errno value in iDetails1 if fopen() or fwrite() failed, 339 - DK4_E_CLOSE_FAILED<br> 340 with errno value in iDetails1 if fclose() failed. 341 */ 342 int 343 dk4dbi_close( 344 dk4_dbi_t *db, 345 dk4_er_t *erp 346 ); 347 348 /** Set or reset option. 349 @param db Database. 350 @param opt Option. 351 @param val New value (1 or 0). 352 @return 1 on success, 0 on error (unknown option). 353 */ 354 int 355 dk4dbi_set_option( 356 dk4_dbi_t *db, 357 int opt, 358 int val 359 ); 360 361 /** Retrieve maximum key size. 362 @param db Database to query. 363 @param erp Error report, may be NULL. 364 @return Value on success (0 means unlimited), 365 0 with erp set on error. 366 367 Error code: 368 - DK4_E_INVALID_ARGUMENTS<br> 369 if db is NULL. 370 */ 371 size_t 372 dk4dbi_get_key_max( 373 const dk4_dbi_t *db, 374 dk4_er_t *erp 375 ); 376 377 /** Retrieve maximum value size. 378 @param db Database to query. 379 @param erp Error report, may be NULL. 380 @return Value on success (0 means unlimited), 381 0 with erp set on error. 382 383 384 Error code: 385 - DK4_E_INVALID_ARGUMENTS<br> 386 if db is NULL. 387 */ 388 size_t 389 dk4dbi_get_val_max( 390 const dk4_dbi_t *db, 391 dk4_er_t *erp 392 ); 393 394 /** Set or overwrite record. 395 @param db Database. 396 @param kp Pointer to key data. 397 @param ks Key data size (number of bytes). 398 @param vp Pointer to value data. Use NULL to delete a record. 399 @param vs Value data size (number of bytes). 400 @param erp Error report, may be NULL. 401 @return 1 on success, 0 on error. 402 403 Error codes: 404 - DK4_E_INVALID_ARGUMENTS<br> 405 if db or kp is NULL or ks is 0, 406 - DK4_E_SYNTAX<br> 407 if the database was opened read-only or ks or vs 408 exceeds a size limit, 409 - DK4_E_NOT_SUPPORTED<br> 410 if db indicates an unsupported backend, 411 - DK4_E_NOT_FOUND<br> 412 if no record to delete was found, 413 - DK4_E_MEMORY_ALLOCATION_FAILED<br> 414 with mem.elsize and mem.nelem 415 set if there is not enough memory available, 416 - DK4_E_WRITE_FAILED<br> 417 if modification of the database failed. 418 */ 419 int 420 dk4dbi_set( 421 dk4_dbi_t *db, 422 const void *kp, 423 size_t ks, 424 const void *vp, 425 size_t vs, 426 dk4_er_t *erp 427 ); 428 429 /** Synchronize changes to file if supported by backend. 430 @param db Database. 431 @param erp error report, may be NULL. 432 @return 1 on success, 0 on error. 433 434 Error codes: 435 - DK4_E_INVALID_ARGUMENTS<br> 436 if db or a backend component is NULL, 437 - DK4_E_NOT_SUPPORTED<br> 438 if db indicates an unsupported backend, 439 - DK4_E_SYNTAX<br> 440 if the database file name does not refer to a regular file, 441 - DK4_E_SEC_CHECK<br> 442 with failed check id in iDetails1 if access is denied by additional 443 security checks, 444 - DK4_E_OPEN_WRITE_FAILED<br> 445 with errno value in iDetails1 if fopen() or fwrite() failed, 446 - DK4_E_WRITE_FAILED<br> 447 if the backend failed to write to a database, 448 - DK4_E_CLOSE_FAILED<br> 449 with errno value in iDetails1 if fclose() failed. 450 */ 451 int 452 dk4dbi_sync( 453 dk4_dbi_t *db, 454 dk4_er_t *erp 455 ); 456 457 /** Retrieve record. 458 @param db Database. 459 @param kp Pointer to key data. 460 @param ks Key data size (number of bytes). 461 @param vp Address of result buffer. 462 @param vs Pointer to buffer size variable (in: size, out: used). 463 @param erp Error report, may be NULL. 464 @return 1 on success, 0 on error. 465 466 Error codes: 467 - DK4_E_INVALID_ARGUMENTS<br> 468 if db, kp, vp or vs is NULL or ks is 0 or *vs is 0 469 or ks exceeds the key size limit, 470 - DK4_E_NOT_SUPPORTED<br> 471 if db indicates an unsupported backend, 472 - DK4_E_NOT_FOUND<br> 473 if no record was found for the key, 474 - DK4_E_BUFFER_TOO_SMALL<br> 475 if the destination buffer is too small. 476 */ 477 int 478 dk4dbi_get( 479 dk4_dbi_t *db, 480 const void *kp, 481 size_t ks, 482 void *vp, 483 size_t *vs, 484 dk4_er_t *erp 485 ); 486 487 /** Delete one record. 488 @param db Database. 489 @param kp Pointer to key data. 490 @param ks Key data size (number of bytes). 491 @param erp Error report, may be NULL. 492 @return 1 on success, 0 on error. 493 494 Error codes: 495 - DK4_E_INVALID_ARGUMENTS<br> 496 if db or kp is NULL or ks is 0, 497 - DK4_E_SYNTAX<br> 498 if the database is opened read-only or ks exceeds the 499 key size limit, 500 - DK4_E_NOT_SUPPORTED<br> 501 if db indicates an unsupported backend, 502 - DK4_E_WRITE_FAILED<br> 503 if modification of the database failed, 504 - DK4_E_NOT_FOUND<br> 505 if no record for the specified key is in the database. 506 */ 507 int 508 dk4dbi_delete( 509 dk4_dbi_t *db, 510 const void *kp, 511 size_t ks, 512 dk4_er_t *erp 513 ); 514 515 /** Traverse database. 516 @param db Database to traverse. 517 @param obj Object to modify during traversal, may be NULL. 518 @param fct Function to execute for all records. 519 @return 1 on success, 0 on error (database traversed), 520 -1 on error (traversal aborted). 521 */ 522 int 523 dk4dbi_traverse( 524 dk4_dbi_t *db, 525 void *obj, 526 dk4dbi_traverse_fct_t *fct 527 ); 528 529 /** Retrieve backend type. 530 @param db Database to check. 531 @return Backend type. 532 */ 533 int 534 dk4dbi_get_type(const dk4_dbi_t *db); 535 536 #if !DK4_ON_WINDOWS 537 #if DK4_CHAR_SIZE == 1 538 #if DK4_HAVE_CHOWN && DK4_HAVE_CHMOD 539 540 /** Change owner and mode for a database. 541 @param db Database to modify. 542 @param user New owner. 543 @param group New owner group. 544 @param mode New file permissions. 545 @param erp Error report, may be NULL. 546 @return 1 on success, 0 on error. 547 548 Error codes: 549 - DK4_E_INVALID_ARGUMENTS<br> 550 if db is NULL, 551 - DK4_E_NOT_SUPPORTED<br> 552 if db indicates an unsupported backend, 553 - DK4_E_SYSTEM<br> 554 with errno value in iDetails1 if a chown or chmod 555 system call failed, 556 - DK4_E_MATH_OVERFLOW<br> 557 if a mathematical overflow occured in size calculation, 558 - DK4_E_BUFFER_TOO_SMALL<br> 559 if the file name is too large for an internal buffer. 560 */ 561 int 562 dk4dbi_change_owner_and_mode( 563 dk4_dbi_t *db, 564 uid_t user, 565 gid_t group, 566 mode_t mode, 567 dk4_er_t *erp 568 ); 569 570 #endif 571 /* if DK4_HAVE_CHOWN && DK4_HAVE_CHMOD */ 572 #endif 573 /* if DK4_CHAR_SIZE == 1 */ 574 #endif 575 /* if !DK4_ON_WINDOWS */ 576 577 #ifdef __cplusplus 578 } 579 #endif 580 581 582 583 584 #endif 585