sqlite3_load_extension.go raw

   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  
   6  //go:build !sqlite_omit_load_extension
   7  // +build !sqlite_omit_load_extension
   8  
   9  package sqlite3
  10  
  11  /*
  12  #ifndef USE_LIBSQLITE3
  13  #include "sqlite3-binding.h"
  14  #else
  15  #include <sqlite3.h>
  16  #endif
  17  #include <stdlib.h>
  18  */
  19  import "C"
  20  import (
  21  	"errors"
  22  	"unsafe"
  23  )
  24  
  25  func (c *SQLiteConn) loadExtensions(extensions []string) error {
  26  	rv := C.sqlite3_enable_load_extension(c.db, 1)
  27  	if rv != C.SQLITE_OK {
  28  		return errors.New(C.GoString(C.sqlite3_errmsg(c.db)))
  29  	}
  30  
  31  	for _, extension := range extensions {
  32  		if err := c.loadExtension(extension, nil); err != nil {
  33  			C.sqlite3_enable_load_extension(c.db, 0)
  34  			return err
  35  		}
  36  	}
  37  
  38  	rv = C.sqlite3_enable_load_extension(c.db, 0)
  39  	if rv != C.SQLITE_OK {
  40  		return errors.New(C.GoString(C.sqlite3_errmsg(c.db)))
  41  	}
  42  
  43  	return nil
  44  }
  45  
  46  // LoadExtension load the sqlite3 extension.
  47  func (c *SQLiteConn) LoadExtension(lib string, entry string) error {
  48  	rv := C.sqlite3_enable_load_extension(c.db, 1)
  49  	if rv != C.SQLITE_OK {
  50  		return errors.New(C.GoString(C.sqlite3_errmsg(c.db)))
  51  	}
  52  
  53  	if err := c.loadExtension(lib, &entry); err != nil {
  54  		C.sqlite3_enable_load_extension(c.db, 0)
  55  		return err
  56  	}
  57  
  58  	rv = C.sqlite3_enable_load_extension(c.db, 0)
  59  	if rv != C.SQLITE_OK {
  60  		return errors.New(C.GoString(C.sqlite3_errmsg(c.db)))
  61  	}
  62  
  63  	return nil
  64  }
  65  
  66  func (c *SQLiteConn) loadExtension(lib string, entry *string) error {
  67  	clib := C.CString(lib)
  68  	defer C.free(unsafe.Pointer(clib))
  69  
  70  	var centry *C.char
  71  	if entry != nil {
  72  		centry = C.CString(*entry)
  73  		defer C.free(unsafe.Pointer(centry))
  74  	}
  75  
  76  	var errMsg *C.char
  77  	defer C.sqlite3_free(unsafe.Pointer(errMsg))
  78  
  79  	rv := C.sqlite3_load_extension(c.db, clib, centry, &errMsg)
  80  	if rv != C.SQLITE_OK {
  81  		return errors.New(C.GoString(errMsg))
  82  	}
  83  
  84  	return nil
  85  }
  86