File: do_sqlite3_extension.c

package info (click to toggle)
ruby-dataobjects-sqlite3 0.10.17-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye
  • size: 332 kB
  • sloc: ansic: 991; ruby: 322; makefile: 4
file content (87 lines) | stat: -rw-r--r-- 2,388 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include <ruby.h>
#include "do_common.h"
#include "do_sqlite3.h"

VALUE cDO_Sqlite3Extension;

/*****************************************************/
/* File used for providing extensions on the default */
/* API that are driver specific.                     */
/*****************************************************/
VALUE do_sqlite3_cExtension_enable_load_extension(VALUE self, VALUE on) {
#ifdef HAVE_SQLITE3_ENABLE_LOAD_EXTENSION
  VALUE id_connection = rb_intern("connection");
  VALUE connection = rb_funcall(self, id_connection, 0);

  if (connection == Qnil) { return Qfalse; }

  // Retrieve the actual connection from the
  VALUE sqlite3_connection = rb_iv_get(connection, "@connection");

  if (sqlite3_connection == Qnil) { return Qfalse; }

  sqlite3 *db;

  Data_Get_Struct(sqlite3_connection, sqlite3, db);


  if (!(db = DATA_PTR(connection))) {
    return Qfalse;
  }

  int status = sqlite3_enable_load_extension(db, on == Qtrue ? 1 : 0);

  if (status != SQLITE_OK) {
    rb_raise(eDO_ConnectionError, "Couldn't enable extension loading");
  }

  return Qtrue;
#else
  return Qfalse;
#endif
}

VALUE do_sqlite3_cExtension_load_extension(VALUE self, VALUE path) {
#ifdef HAVE_SQLITE3_ENABLE_LOAD_EXTENSION
  VALUE connection = rb_iv_get(self, "@connection");

  if (connection == Qnil) { return Qfalse; }

  // Retrieve the actual connection from the object
  VALUE sqlite3_connection = rb_iv_get(connection, "@connection");

  if (sqlite3_connection == Qnil) { return Qfalse; }

  sqlite3 *db;

  Data_Get_Struct(sqlite3_connection, sqlite3, db);

  const char *extension_path  = rb_str_ptr_readonly(path);
  char *errmsg = sqlite3_malloc(1024);

  if (!errmsg) {
    return Qfalse;
  }

  int status = sqlite3_load_extension(db, extension_path, 0, &errmsg);

  if (status != SQLITE_OK) {
    VALUE errexp = rb_exc_new2(eDO_ConnectionError, errmsg);

    sqlite3_free(errmsg);
    rb_exc_raise(errexp);
  }

  sqlite3_free(errmsg);
  return Qtrue;
#else
  return Qfalse;
#endif
}

void Init_do_sqlite3_extension() {
  cDO_Sqlite3Extension = rb_define_class_under(mDO_Sqlite3, "Extension", cDO_Extension);
  rb_global_variable(&cDO_Sqlite3Extension);
  rb_define_method(cDO_Sqlite3Extension, "load_extension", do_sqlite3_cExtension_load_extension, 1);
  rb_define_method(cDO_Sqlite3Extension, "enable_load_extension", do_sqlite3_cExtension_enable_load_extension, 1);
}