astdb2sqlite3.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 1999 - 2005, Digium, Inc.
  5. *
  6. * Mark Spencer <markster@digium.com>
  7. *
  8. * See http://www.asterisk.org for more information about
  9. * the Asterisk project. Please do not directly contact
  10. * any of the maintainers of this project for assistance;
  11. * the project provides a web site, mailing lists and IRC
  12. * channels for your use.
  13. *
  14. * This program is free software, distributed under the terms of
  15. * the GNU General Public License Version 2. See the LICENSE file
  16. * at the top of the source tree.
  17. */
  18. /*! \file
  19. *
  20. * \brief Berkeley DB to SQLite3 converter
  21. *
  22. * \author Terry Wilson <twilson@digium.com>
  23. */
  24. /*** MODULEINFO
  25. <support_level>core</support_level>
  26. ***/
  27. #include "asterisk.h"
  28. //ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  29. #include <sys/types.h>
  30. #include <sys/stat.h>
  31. #include <fcntl.h>
  32. #include <unistd.h>
  33. #include <sqlite3.h>
  34. #include <libgen.h> /* OS X doesn't have the basename function in strings.h */
  35. #include "db1-ast/include/db.h"
  36. #define MAX_DB_FIELD 256
  37. #define MIN(a,b) \
  38. ({ typeof (a) _a = (a); \
  39. typeof (b) _b = (b); \
  40. a < _b ? _a : _b; })
  41. static sqlite3 *astdb;
  42. #define DEFINE_SQL_STATEMENT(stmt,sql) static sqlite3_stmt *stmt; \
  43. const char stmt##_sql[] = sql;
  44. DEFINE_SQL_STATEMENT(put_stmt, "INSERT OR REPLACE INTO astdb (key, value) VALUES (?, ?)")
  45. DEFINE_SQL_STATEMENT(create_astdb_stmt, "CREATE TABLE IF NOT EXISTS astdb(key VARCHAR(256), value VARCHAR(256), PRIMARY KEY(key))")
  46. static int db_execute_transaction_sql(const char *sql)
  47. {
  48. char *errmsg = NULL;
  49. int res =0;
  50. sqlite3_exec(astdb, sql, NULL, NULL, &errmsg);
  51. if (errmsg) {
  52. fprintf(stderr, "Error executing SQL: %s\n", errmsg);
  53. sqlite3_free(errmsg);
  54. res = -1;
  55. }
  56. return res;
  57. }
  58. static int ast_db_begin_transaction(void)
  59. {
  60. return db_execute_transaction_sql("BEGIN TRANSACTION");
  61. }
  62. static int ast_db_commit_transaction(void)
  63. {
  64. return db_execute_transaction_sql("COMMIT");
  65. }
  66. static int ast_db_rollback_transaction(void)
  67. {
  68. return db_execute_transaction_sql("ROLLBACK");
  69. }
  70. static int db_put_raw(const char *key, size_t keylen, const char *value, size_t valuelen)
  71. {
  72. int res = 0;
  73. if (sqlite3_bind_text(put_stmt, 1, key, keylen, SQLITE_STATIC) != SQLITE_OK) {
  74. fprintf(stderr, "Couldn't bind key to stmt: %s\n", sqlite3_errmsg(astdb));
  75. res = -1;
  76. } else if (sqlite3_bind_text(put_stmt, 2, value, valuelen, SQLITE_STATIC) != SQLITE_OK) {
  77. fprintf(stderr, "Couldn't bind value to stmt: %s\n", sqlite3_errmsg(astdb));
  78. res = -1;
  79. } else if (sqlite3_step(put_stmt) != SQLITE_DONE) {
  80. fprintf(stderr, "Couldn't execute statement: %s\n", sqlite3_errmsg(astdb));
  81. res = -1;
  82. }
  83. sqlite3_reset(put_stmt);
  84. return res;
  85. }
  86. static int convert_bdb_to_sqlite3(const char *bdb_dbname)
  87. {
  88. DB *bdb;
  89. DBT key = { 0, }, value = { 0, }, last_key = { 0, };
  90. int res, last = 0;
  91. char last_key_s[MAX_DB_FIELD];
  92. if (!(bdb = dbopen(bdb_dbname, O_RDONLY, AST_FILE_MODE, DB_BTREE, NULL))) {
  93. fprintf(stderr, "Unable to open Asterisk database '%s'\n", bdb_dbname);
  94. return -1;
  95. }
  96. if (bdb->seq(bdb, &last_key, &value, R_LAST)) {
  97. /* Empty database */
  98. return 0;
  99. }
  100. memcpy(last_key_s, last_key.data, MIN(last_key.size - 1, sizeof(last_key_s)));
  101. last_key_s[last_key.size - 1] = '\0';
  102. for (res = bdb->seq(bdb, &key, &value, R_FIRST);
  103. !res; res = bdb->seq(bdb, &key, &value, R_NEXT)) {
  104. last = !strcmp(key.data, last_key_s);
  105. db_put_raw((const char *) key.data, key.size - 1, (const char *) value.data, value.size - 1);
  106. if (last) {
  107. break;
  108. }
  109. }
  110. bdb->close(bdb);
  111. return 0;
  112. }
  113. static int init_stmt(sqlite3_stmt **stmt, const char *sql, size_t len)
  114. {
  115. if (sqlite3_prepare(astdb, sql, len, stmt, NULL) != SQLITE_OK) {
  116. fprintf(stderr, "Couldn't prepare statement '%s': %s\n", sql, sqlite3_errmsg(astdb));
  117. return -1;
  118. }
  119. return 0;
  120. }
  121. static int db_create_astdb(void)
  122. {
  123. if (init_stmt(&create_astdb_stmt, create_astdb_stmt_sql, sizeof(create_astdb_stmt_sql))) {
  124. return -1;
  125. }
  126. ast_db_begin_transaction();
  127. if (sqlite3_step(create_astdb_stmt) != SQLITE_DONE) {
  128. fprintf(stderr, "Couldn't create astdb table: %s\n", sqlite3_errmsg(astdb));
  129. ast_db_rollback_transaction();
  130. sqlite3_reset(create_astdb_stmt);
  131. return -1;
  132. }
  133. ast_db_commit_transaction();
  134. sqlite3_reset(create_astdb_stmt);
  135. return 0;
  136. }
  137. static int init_statements(void)
  138. {
  139. /* Don't initialize create_astdb_statement here as the astdb table needs to exist
  140. * brefore these statements can be initialized */
  141. return init_stmt(&put_stmt, put_stmt_sql, sizeof(put_stmt_sql));
  142. }
  143. static int db_open(const char *dbname)
  144. {
  145. if (sqlite3_open(dbname, &astdb) != SQLITE_OK) {
  146. fprintf(stderr, "Unable to open Asterisk database '%s': %s\n", dbname, sqlite3_errmsg(astdb));
  147. sqlite3_close(astdb);
  148. return -1;
  149. }
  150. return 0;
  151. }
  152. static int sql_db_init(const char *dbname)
  153. {
  154. if (db_open(dbname) || db_create_astdb() || init_statements()) {
  155. return -1;
  156. }
  157. return 0;
  158. }
  159. int main(int argc, char *argv[])
  160. {
  161. char *dbname;
  162. struct stat dont_care;
  163. if (argc != 2) {
  164. fprintf(stderr, "%s takes the path of astdb as its only argument\n", basename(argv[0]));
  165. exit(-1);
  166. }
  167. if (stat(argv[1], &dont_care)) {
  168. fprintf(stderr, "Unable to open %s: %s\n", argv[1], strerror(errno));
  169. exit(-1);
  170. }
  171. if (!(dbname = alloca(strlen(argv[1]) + sizeof(".sqlite3")))) {
  172. exit(-1);
  173. }
  174. strcpy(dbname, argv[1]);
  175. strcat(dbname, ".sqlite3");
  176. if (!stat(dbname, &dont_care)) {
  177. fprintf(stderr, "%s already exists!\n", dbname);
  178. exit(-1);
  179. }
  180. if (sql_db_init(dbname)) {
  181. exit(-1);
  182. }
  183. if (convert_bdb_to_sqlite3(argv[1])) {
  184. fprintf(stderr, "Database conversion failed!\n");
  185. exit(-1);
  186. sqlite3_close(astdb);
  187. }
  188. sqlite3_close(astdb);
  189. return 0;
  190. }