@@ -23,6 +23,83 @@ typedef struct statement
23
23
sqlite3_stmt * statement ;
24
24
} statement_t ;
25
25
26
+ static void *
27
+ exqlite_malloc (int bytes )
28
+ {
29
+ assert (bytes > 0 );
30
+
31
+ int * p = enif_alloc (bytes + sizeof (int ));
32
+ if (p ) {
33
+ p [0 ] = bytes ;
34
+ p ++ ;
35
+ }
36
+
37
+ return p ;
38
+ }
39
+
40
+ static void
41
+ exqlite_free (void * prior )
42
+ {
43
+ if (!prior ) {
44
+ return ;
45
+ }
46
+
47
+ int * p = prior ;
48
+
49
+ // Shift the pointer back to free the proper block of data
50
+ p -- ;
51
+
52
+ return enif_free (p );
53
+ }
54
+
55
+ static void *
56
+ exqlite_realloc (void * prior , int bytes )
57
+ {
58
+ assert (prior );
59
+ assert (bytes > 0 );
60
+
61
+ int * p = prior ;
62
+ p -- ;
63
+
64
+ p = enif_realloc (p , bytes + sizeof (int ));
65
+ if (p ) {
66
+ p [0 ] = bytes ;
67
+ p ++ ;
68
+ }
69
+
70
+ return p ;
71
+ }
72
+
73
+ static int
74
+ exqlite_mem_size (void * prior )
75
+ {
76
+ if (!prior ) {
77
+ return 0 ;
78
+ }
79
+
80
+ int * p = prior ;
81
+ p -- ;
82
+
83
+ return p [0 ];
84
+ }
85
+
86
+ static int
87
+ exqlite_mem_round_up (int bytes )
88
+ {
89
+ return (bytes + 7 ) & ~7 ;
90
+ }
91
+
92
+ static int
93
+ exqlite_mem_init (void * ptr )
94
+ {
95
+ return SQLITE_OK ;
96
+ }
97
+
98
+ static void
99
+ exqlite_mem_shutdown (void * ptr )
100
+ {
101
+ }
102
+
26
103
static const char *
27
104
get_sqlite3_error_msg (int rc , sqlite3 * db )
28
105
{
@@ -496,7 +573,7 @@ exqlite_multi_step(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
496
573
return enif_make_tuple2 (env , make_atom (env , "done" ), rows );
497
574
498
575
case SQLITE_ROW :
499
- row = make_row (env , statement -> statement );
576
+ row = make_row (env , statement -> statement );
500
577
rows = enif_make_list_cell (env , row , rows );
501
578
break ;
502
579
@@ -533,10 +610,9 @@ exqlite_step(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
533
610
switch (rc ) {
534
611
case SQLITE_ROW :
535
612
return enif_make_tuple2 (
536
- env ,
537
- make_atom (env , "row" ),
538
- make_row (env , statement -> statement )
539
- );
613
+ env ,
614
+ make_atom (env , "row" ),
615
+ make_row (env , statement -> statement ));
540
616
case SQLITE_BUSY :
541
617
return make_atom (env , "busy" );
542
618
case SQLITE_DONE :
@@ -651,8 +727,8 @@ exqlite_serialize(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
651
727
652
728
connection_t * conn = NULL ;
653
729
ErlNifBinary database_name ;
654
- ERL_NIF_TERM eos = enif_make_int (env , 0 );
655
- unsigned char * buffer = NULL ;
730
+ ERL_NIF_TERM eos = enif_make_int (env , 0 );
731
+ unsigned char * buffer = NULL ;
656
732
sqlite3_int64 buffer_size = 0 ;
657
733
ERL_NIF_TERM serialized ;
658
734
@@ -668,7 +744,7 @@ exqlite_serialize(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
668
744
return make_error_tuple (env , "database_name_not_iolist" );
669
745
}
670
746
671
- buffer = sqlite3_serialize (conn -> db , (char * ) database_name .data , & buffer_size , 0 );
747
+ buffer = sqlite3_serialize (conn -> db , (char * )database_name .data , & buffer_size , 0 );
672
748
if (!buffer ) {
673
749
return make_error_tuple (env , "serialization_failed" );
674
750
}
@@ -684,13 +760,13 @@ exqlite_deserialize(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
684
760
{
685
761
assert (env );
686
762
687
- connection_t * conn = NULL ;
763
+ connection_t * conn = NULL ;
688
764
unsigned char * buffer = NULL ;
689
765
ErlNifBinary database_name ;
690
766
ERL_NIF_TERM eos = enif_make_int (env , 0 );
691
767
ErlNifBinary serialized ;
692
- int size = 0 ;
693
- int rc = 0 ;
768
+ int size = 0 ;
769
+ int rc = 0 ;
694
770
int flags = SQLITE_DESERIALIZE_FREEONCLOSE | SQLITE_DESERIALIZE_RESIZEABLE ;
695
771
696
772
if (argc != 3 ) {
@@ -709,7 +785,7 @@ exqlite_deserialize(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
709
785
return enif_make_badarg (env );
710
786
}
711
787
712
- size = serialized .size ;
788
+ size = serialized .size ;
713
789
buffer = sqlite3_malloc (size );
714
790
if (!buffer ) {
715
791
return make_error_tuple (env , "deserialization_failed" );
@@ -785,6 +861,18 @@ on_load(ErlNifEnv* env, void** priv, ERL_NIF_TERM info)
785
861
{
786
862
assert (env );
787
863
864
+ static const sqlite3_mem_methods methods = {
865
+ exqlite_malloc ,
866
+ exqlite_free ,
867
+ exqlite_realloc ,
868
+ exqlite_mem_size ,
869
+ exqlite_mem_round_up ,
870
+ exqlite_mem_init ,
871
+ exqlite_mem_shutdown ,
872
+ 0 };
873
+
874
+ sqlite3_config (SQLITE_CONFIG_MALLOC , & methods );
875
+
788
876
connection_type = enif_open_resource_type (
789
877
env ,
790
878
"exqlite" ,
@@ -810,6 +898,13 @@ on_load(ErlNifEnv* env, void** priv, ERL_NIF_TERM info)
810
898
return 0 ;
811
899
}
812
900
901
+ static void
902
+ on_unload (ErlNifEnv * caller_env , void * priv_data )
903
+ {
904
+ assert (env );
905
+
906
+ sqlite3_config (SQLITE_CONFIG_MALLOC , NULL );
907
+ }
813
908
814
909
//
815
910
// Enable extension loading
@@ -870,4 +965,4 @@ static ErlNifFunc nif_funcs[] = {
870
965
#define ERL_NIF_INIT_DECL (MODNAME ) ErlNifEntry* sqlite3_nif_nif_init(ERL_NIF_INIT_ARGS)
871
966
#endif
872
967
873
- ERL_NIF_INIT (Elixir .Exqlite .Sqlite3NIF , nif_funcs , on_load , NULL , NULL , NULL )
968
+ ERL_NIF_INIT (Elixir .Exqlite .Sqlite3NIF , nif_funcs , on_load , NULL , NULL , on_unload )
0 commit comments