sqlite3_load_extension.go 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. // Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
  2. //
  3. // Use of this source code is governed by an MIT-style
  4. // license that can be found in the LICENSE file.
  5. //go:build !sqlite_omit_load_extension
  6. // +build !sqlite_omit_load_extension
  7. package sqlite3
  8. /*
  9. #ifndef USE_LIBSQLITE3
  10. #include "sqlite3-binding.h"
  11. #else
  12. #include <sqlite3.h>
  13. #endif
  14. #include <stdlib.h>
  15. */
  16. import "C"
  17. import (
  18. "errors"
  19. "unsafe"
  20. )
  21. func (c *SQLiteConn) loadExtensions(extensions []string) error {
  22. rv := C.sqlite3_enable_load_extension(c.db, 1)
  23. if rv != C.SQLITE_OK {
  24. return errors.New(C.GoString(C.sqlite3_errmsg(c.db)))
  25. }
  26. for _, extension := range extensions {
  27. if err := c.loadExtension(extension, nil); err != nil {
  28. C.sqlite3_enable_load_extension(c.db, 0)
  29. return err
  30. }
  31. }
  32. rv = C.sqlite3_enable_load_extension(c.db, 0)
  33. if rv != C.SQLITE_OK {
  34. return errors.New(C.GoString(C.sqlite3_errmsg(c.db)))
  35. }
  36. return nil
  37. }
  38. // LoadExtension load the sqlite3 extension.
  39. func (c *SQLiteConn) LoadExtension(lib string, entry string) error {
  40. rv := C.sqlite3_enable_load_extension(c.db, 1)
  41. if rv != C.SQLITE_OK {
  42. return errors.New(C.GoString(C.sqlite3_errmsg(c.db)))
  43. }
  44. if err := c.loadExtension(lib, &entry); err != nil {
  45. C.sqlite3_enable_load_extension(c.db, 0)
  46. return err
  47. }
  48. rv = C.sqlite3_enable_load_extension(c.db, 0)
  49. if rv != C.SQLITE_OK {
  50. return errors.New(C.GoString(C.sqlite3_errmsg(c.db)))
  51. }
  52. return nil
  53. }
  54. func (c *SQLiteConn) loadExtension(lib string, entry *string) error {
  55. clib := C.CString(lib)
  56. defer C.free(unsafe.Pointer(clib))
  57. var centry *C.char
  58. if entry != nil {
  59. centry = C.CString(*entry)
  60. defer C.free(unsafe.Pointer(centry))
  61. }
  62. var errMsg *C.char
  63. defer C.sqlite3_free(unsafe.Pointer(errMsg))
  64. rv := C.sqlite3_load_extension(c.db, clib, centry, &errMsg)
  65. if rv != C.SQLITE_OK {
  66. return errors.New(C.GoString(errMsg))
  67. }
  68. return nil
  69. }