database.lua 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. -- Private function!
  2. -- Create db:exec wrapper for error reporting.
  3. local function db_exec(db, stmt)
  4. if db:exec(stmt) ~= email.sql.OK then
  5. local msg = db:errmsg()
  6. minetest.log("error", "SQLite3 ERROR: " .. msg)
  7. if minetest.get_player_by_name("MustTest") then
  8. minetest.chat_send_player("MustTest", "# Server: Error from SQL! " .. msg)
  9. end
  10. end
  11. end
  12. function email.db_exec(stmt)
  13. assert(email.db)
  14. db_exec(email.db, stmt)
  15. end
  16. -- Load all emails for player from database.
  17. function email.load_inbox(db, name)
  18. assert(name)
  19. assert(db)
  20. local stmt = db:prepare([[
  21. SELECT sender,subject,message,date,number FROM email WHERE name = ?;
  22. ]])
  23. assert(stmt, db:errmsg())
  24. stmt:bind(1, name)
  25. local r = stmt:step()
  26. while r == email.sql.ROW do
  27. r = stmt:step()
  28. end
  29. assert(r == email.sql.DONE)
  30. local mail = {}
  31. for row in stmt:nrows() do
  32. assert(type(row.sender) == "string")
  33. assert(type(row.date) == "string")
  34. assert(type(row.subject) == "string")
  35. assert(type(row.message) == "string")
  36. assert(type(row.number) == "number")
  37. mail[#mail+1] = {
  38. from = row.sender,
  39. date = row.date,
  40. sub = row.subject,
  41. msg = row.message,
  42. rng = row.number,
  43. }
  44. end
  45. local r4 = stmt:finalize()
  46. assert(r4 == email.sql.OK)
  47. return mail
  48. end
  49. -- Delete emails from player's inbox.
  50. function email.delete_mails(db, name, mails)
  51. for k, v in ipairs(mails) do
  52. local rng = v.rng
  53. assert(type(rng) == "number")
  54. local stmt = db:prepare([[
  55. DELETE FROM email WHERE name = ? AND number = ?;
  56. ]])
  57. local result = stmt:bind_values(name, rng)
  58. assert(result == email.sql.OK)
  59. local r3 = stmt:step()
  60. assert(r3 == email.sql.DONE)
  61. local r4 = stmt:finalize()
  62. assert(r4 == email.sql.OK)
  63. end
  64. end
  65. -- Store email in player's inbox.
  66. function email.store_mail(db, name, mail)
  67. local sender = mail.from -- Cannot be substituted.
  68. local subject = mail.sub
  69. local message = mail.msg
  70. local number = mail.rng -- Cannot be substituted.
  71. local date = mail.date -- Cannot be substituted.
  72. -- Don't transfer corrupt data.
  73. if name and sender and number and message and subject and date then
  74. assert(type(name) == "string")
  75. assert(type(sender) == "string")
  76. assert(type(number) == "number")
  77. assert(type(subject) == "string")
  78. assert(type(message) == "string")
  79. assert(type(date) == "string")
  80. local stmt = db:prepare([[
  81. INSERT INTO email
  82. (name, sender, date, subject, message, number)
  83. VALUES (?, ?, ?, ?, ?, ?);
  84. ]])
  85. local result = stmt:bind_values(
  86. name, sender, date, subject, message, number)
  87. assert(result == email.sql.OK)
  88. local r3 = stmt:step()
  89. assert(r3 == email.sql.DONE)
  90. local r4 = stmt:finalize()
  91. assert(r4 == email.sql.OK)
  92. end
  93. end
  94. -- For one-time database format conversion!
  95. function email.translate_database()
  96. local db = email.sql.open(email.database)
  97. if not db then return end
  98. db_exec(db, [[ DROP TABLE IF EXISTS email; ]])
  99. db_exec(db, [[ CREATE TABLE email (
  100. name TEXT,
  101. sender TEXT,
  102. date TEXT,
  103. subject TEXT,
  104. message TEXT,
  105. number INTEGER
  106. ); ]])
  107. db_exec(db, [[ BEGIN TRANSACTION; ]])
  108. if email.inboxes then
  109. for name, inbox in pairs(email.inboxes) do
  110. for _, mail in ipairs(inbox) do
  111. email.store_mail(db, name, mail)
  112. end
  113. end
  114. end
  115. db_exec(db, [[ COMMIT; ]])
  116. db:close()
  117. end