@@ -448,194 +448,124 @@ exqlite_prepare(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
448
448
}
449
449
450
450
static ERL_NIF_TERM
451
- bind (ErlNifEnv * env , const ERL_NIF_TERM arg , sqlite3_stmt * statement , int index )
451
+ raise_badarg (ErlNifEnv * env , ERL_NIF_TERM term )
452
452
{
453
- int rc ;
454
- int the_int ;
455
- ErlNifSInt64 the_long_int ;
456
- double the_double ;
457
- char the_atom [MAX_ATOM_LENGTH + 1 ];
458
- ErlNifBinary the_blob ;
459
- int arity ;
460
- const ERL_NIF_TERM * tuple ;
461
-
462
- if (enif_get_int64 (env , arg , & the_long_int )) {
463
- rc = sqlite3_bind_int64 (statement , index , the_long_int );
464
- if (rc == SQLITE_OK ) {
465
- return make_atom (env , "ok" );
466
- }
467
-
468
- return enif_raise_exception (
469
- env ,
470
- make_bind_error (
471
- env ,
472
- make_message (env , "Failed to bind argument as 64 bit integer" ),
473
- arg ));
474
- }
453
+ ERL_NIF_TERM badarg = enif_make_tuple2 (env , make_atom (env , "badarg" ), term );
454
+ return enif_raise_exception (env , badarg );
455
+ }
475
456
476
- if (enif_get_int (env , arg , & the_int )) {
477
- rc = sqlite3_bind_int (statement , index , the_int );
478
- if (rc == SQLITE_OK ) {
479
- return make_atom (env , "ok" );
480
- }
457
+ static ERL_NIF_TERM
458
+ exqlite_reset (ErlNifEnv * env , int argc , const ERL_NIF_TERM argv [])
459
+ {
460
+ statement_t * statement ;
461
+ if (!enif_get_resource (env , argv [0 ], statement_type , (void * * )& statement ))
462
+ return raise_badarg (env , argv [0 ]);
481
463
482
- return enif_raise_exception (
483
- env ,
484
- make_bind_error (
485
- env ,
486
- make_message (env , "Failed to bind argument as integer" ),
487
- arg ));
488
- }
464
+ sqlite3_reset (statement -> statement );
465
+ return make_atom (env , "ok" );
466
+ }
489
467
490
- if (enif_get_double (env , arg , & the_double )) {
491
- rc = sqlite3_bind_double (statement , index , the_double );
492
- if (rc == SQLITE_OK ) {
493
- return make_atom (env , "ok" );
494
- }
468
+ static ERL_NIF_TERM
469
+ exqlite_bind_parameter_count (ErlNifEnv * env , int argc , const ERL_NIF_TERM argv [])
470
+ {
495
471
496
- return enif_raise_exception (
497
- env ,
498
- make_bind_error (
499
- env ,
500
- make_message (env , "Failed to bind argument as double" ),
501
- arg ));
502
- }
472
+ statement_t * statement ;
473
+ if (!enif_get_resource (env , argv [0 ], statement_type , (void * * )& statement ))
474
+ return raise_badarg (env , argv [0 ]);
503
475
504
- if (enif_get_atom (env , arg , the_atom , sizeof (the_atom ), ERL_NIF_LATIN1 )) {
505
- if (0 == strcmp ("undefined" , the_atom ) || 0 == strcmp ("nil" , the_atom )) {
506
- rc = sqlite3_bind_null (statement , index );
507
- if (rc == SQLITE_OK ) {
508
- return make_atom (env , "ok" );
509
- }
476
+ int bind_parameter_count = sqlite3_bind_parameter_count (statement -> statement );
477
+ return enif_make_int (env , bind_parameter_count );
478
+ }
510
479
511
- return enif_raise_exception (
512
- env ,
513
- make_bind_error (
514
- env ,
515
- make_message (env , "Failed to bind argument as null" ),
516
- arg ));
517
- }
480
+ static ERL_NIF_TERM
481
+ exqlite_bind_text (ErlNifEnv * env , int argc , const ERL_NIF_TERM argv [])
482
+ {
483
+ statement_t * statement ;
484
+ if (!enif_get_resource (env , argv [0 ], statement_type , (void * * )& statement ))
485
+ return raise_badarg (env , argv [0 ]);
518
486
519
- rc = sqlite3_bind_text (statement , index , the_atom , strlen (the_atom ), SQLITE_TRANSIENT );
520
- if (rc == SQLITE_OK ) {
521
- return make_atom (env , "ok" );
522
- }
487
+ unsigned int idx ;
488
+ if (!enif_get_uint (env , argv [1 ], & idx ))
489
+ return raise_badarg (env , argv [1 ]);
523
490
524
- return enif_raise_exception (
525
- env ,
526
- make_bind_error (
527
- env ,
528
- make_message (env , "Failed to bind argument as text" ),
529
- arg ));
530
- }
491
+ ErlNifBinary text ;
492
+ if (!enif_inspect_binary (env , argv [2 ], & text ))
493
+ return raise_badarg (env , argv [2 ]);
531
494
532
- if (enif_inspect_iolist_as_binary (env , arg , & the_blob )) {
533
- rc = sqlite3_bind_text (statement , index , (char * )the_blob .data , the_blob .size , SQLITE_TRANSIENT );
534
- if (rc == SQLITE_OK ) {
535
- return make_atom (env , "ok" );
536
- }
495
+ int rc = sqlite3_bind_text (statement -> statement , idx , (char * )text .data , text .size , SQLITE_TRANSIENT );
496
+ return enif_make_int (env , rc );
497
+ }
537
498
538
- return enif_raise_exception (
539
- env ,
540
- make_bind_error (
541
- env ,
542
- make_message (env , "Failed to bind argument as text" ),
543
- arg ));
544
- }
499
+ static ERL_NIF_TERM
500
+ exqlite_bind_blob (ErlNifEnv * env , int argc , const ERL_NIF_TERM argv [])
501
+ {
502
+ statement_t * statement ;
503
+ if (!enif_get_resource (env , argv [0 ], statement_type , (void * * )& statement ))
504
+ return raise_badarg (env , argv [0 ]);
545
505
546
- if (enif_get_tuple (env , arg , & arity , & tuple )) {
547
- if (arity != 2 ) {
548
- return enif_raise_exception (
549
- env ,
550
- make_bind_error (
551
- env ,
552
- make_message (env , "Failed to bind argument as blob" ),
553
- arg ));
554
- }
506
+ unsigned int idx ;
507
+ if (!enif_get_uint (env , argv [1 ], & idx ))
508
+ return raise_badarg (env , argv [1 ]);
555
509
556
- if (enif_get_atom (env , tuple [0 ], the_atom , sizeof (the_atom ), ERL_NIF_LATIN1 )) {
557
- if (0 == strcmp ("blob" , the_atom )) {
558
- if (enif_inspect_iolist_as_binary (env , tuple [1 ], & the_blob )) {
559
- rc = sqlite3_bind_blob (statement , index , the_blob .data , the_blob .size , SQLITE_TRANSIENT );
560
- if (rc == SQLITE_OK ) {
561
- return make_atom (env , "ok" );
562
- }
563
-
564
- return enif_raise_exception (
565
- env ,
566
- make_bind_error (
567
- env ,
568
- make_message (env , "Failed to bind argument as blob" ),
569
- arg ));
570
- }
571
- }
572
- }
573
- }
510
+ ErlNifBinary blob ;
511
+ if (!enif_inspect_binary (env , argv [2 ], & blob ))
512
+ return raise_badarg (env , argv [2 ]);
574
513
575
- return enif_raise_exception (
576
- env ,
577
- make_bind_error (
578
- env ,
579
- make_message (env , "Failed to bind argument" ),
580
- arg ));
514
+ int rc = sqlite3_bind_blob (statement -> statement , idx , (char * )blob .data , blob .size , SQLITE_TRANSIENT );
515
+ return enif_make_int (env , rc );
581
516
}
582
517
583
- ///
584
- /// @brief Binds arguments to the sql statement
585
- ///
586
518
static ERL_NIF_TERM
587
- exqlite_bind (ErlNifEnv * env , int argc , const ERL_NIF_TERM argv [])
519
+ exqlite_bind_integer (ErlNifEnv * env , int argc , const ERL_NIF_TERM argv [])
588
520
{
589
- assert (env );
521
+ statement_t * statement ;
522
+ if (!enif_get_resource (env , argv [0 ], statement_type , (void * * )& statement ))
523
+ return raise_badarg (env , argv [0 ]);
590
524
591
- unsigned int parameter_count = 0 ;
592
- unsigned int argument_list_length = 0 ;
593
- connection_t * conn = NULL ;
594
- statement_t * statement = NULL ;
595
- ERL_NIF_TERM list ;
596
- ERL_NIF_TERM head ;
597
- ERL_NIF_TERM tail ;
525
+ unsigned int idx ;
526
+ if (!enif_get_uint (env , argv [1 ], & idx ))
527
+ return raise_badarg (env , argv [1 ]);
598
528
599
- if (argc != 3 ) {
600
- return enif_make_badarg (env );
601
- }
602
-
603
- if (!enif_get_resource (env , argv [0 ], connection_type , (void * * )& conn )) {
604
- return make_error_tuple (env , "invalid_connection" );
605
- }
606
-
607
- if (!enif_get_resource (env , argv [1 ], statement_type , (void * * )& statement )) {
608
- return make_error_tuple (env , "invalid_statement" );
609
- }
529
+ ErlNifSInt64 i ;
530
+ if (!enif_get_int64 (env , argv [2 ], & i ))
531
+ return raise_badarg (env , argv [2 ]);
610
532
611
- if (! enif_get_list_length ( env , argv [ 2 ], & argument_list_length )) {
612
- return make_error_tuple (env , "bad_argument_list" );
613
- }
533
+ int rc = sqlite3_bind_int64 ( statement -> statement , idx , i );
534
+ return enif_make_int (env , rc );
535
+ }
614
536
615
- parameter_count = (unsigned int )sqlite3_bind_parameter_count (statement -> statement );
616
- if (parameter_count != argument_list_length ) {
617
- return make_error_tuple (env , "arguments_wrong_length" );
618
- }
537
+ static ERL_NIF_TERM
538
+ exqlite_bind_float (ErlNifEnv * env , int argc , const ERL_NIF_TERM argv [])
539
+ {
540
+ statement_t * statement ;
541
+ if (!enif_get_resource (env , argv [0 ], statement_type , (void * * )& statement ))
542
+ return raise_badarg (env , argv [0 ]);
619
543
620
- sqlite3_reset (statement -> statement );
544
+ unsigned int idx ;
545
+ if (!enif_get_uint (env , argv [1 ], & idx ))
546
+ return raise_badarg (env , argv [1 ]);
621
547
622
- list = argv [2 ];
623
- for (unsigned int i = 0 ; i < argument_list_length ; i ++ ) {
624
- enif_get_list_cell (env , list , & head , & tail );
625
- ERL_NIF_TERM result = bind (env , head , statement -> statement , i + 1 );
548
+ double f ;
549
+ if (!enif_get_double (env , argv [2 ], & f ))
550
+ return raise_badarg (env , argv [2 ]);
626
551
627
- // We are going to ignore this, we have to pass it.
628
- ERL_NIF_TERM reason ;
552
+ int rc = sqlite3_bind_double (statement -> statement , idx , f );
553
+ return enif_make_int (env , rc );
554
+ }
629
555
630
- // Bind will set an exception if anything happens during that phase.
631
- if (enif_has_pending_exception (env , & reason )) {
632
- return make_error_tuple (env , "failed_to_bind_argument" );
633
- }
556
+ static ERL_NIF_TERM
557
+ exqlite_bind_null (ErlNifEnv * env , int argc , const ERL_NIF_TERM argv [])
558
+ {
559
+ statement_t * statement ;
560
+ if (!enif_get_resource (env , argv [0 ], statement_type , (void * * )& statement ))
561
+ return raise_badarg (env , argv [0 ]);
634
562
635
- list = tail ;
636
- }
563
+ unsigned int idx ;
564
+ if (!enif_get_uint (env , argv [1 ], & idx ))
565
+ return raise_badarg (env , argv [1 ]);
637
566
638
- return make_atom (env , "ok" );
567
+ int rc = sqlite3_bind_null (statement -> statement , idx );
568
+ return enif_make_int (env , rc );
639
569
}
640
570
641
571
static ERL_NIF_TERM
@@ -1272,6 +1202,38 @@ exqlite_interrupt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
1272
1202
return make_atom (env , "ok" );
1273
1203
}
1274
1204
1205
+ static ERL_NIF_TERM
1206
+ exqlite_errmsg (ErlNifEnv * env , int argc , const ERL_NIF_TERM argv [])
1207
+ {
1208
+ connection_t * conn ;
1209
+ statement_t * statement ;
1210
+ const char * msg ;
1211
+
1212
+ if (enif_get_resource (env , argv [0 ], connection_type , (void * * )& conn )) {
1213
+ msg = sqlite3_errmsg (conn -> db );
1214
+ } else if (enif_get_resource (env , argv [0 ], statement_type , (void * * )& statement )) {
1215
+ msg = sqlite3_errmsg (sqlite3_db_handle (statement -> statement ));
1216
+ } else {
1217
+ return raise_badarg (env , argv [0 ]);
1218
+ }
1219
+
1220
+ if (!msg )
1221
+ return make_atom (env , "nil" );
1222
+
1223
+ return make_binary (env , msg , strlen (msg ));
1224
+ }
1225
+
1226
+ static ERL_NIF_TERM
1227
+ exqlite_errstr (ErlNifEnv * env , int argc , const ERL_NIF_TERM argv [])
1228
+ {
1229
+ int rc ;
1230
+ if (!enif_get_int (env , argv [0 ], & rc ))
1231
+ return raise_badarg (env , argv [0 ]);
1232
+
1233
+ const char * msg = sqlite3_errstr (rc );
1234
+ return make_binary (env , msg , strlen (msg ));
1235
+ }
1236
+
1275
1237
//
1276
1238
// Most of our nif functions are going to be IO bounded
1277
1239
//
@@ -1282,7 +1244,13 @@ static ErlNifFunc nif_funcs[] = {
1282
1244
{"execute" , 2 , exqlite_execute , ERL_NIF_DIRTY_JOB_IO_BOUND },
1283
1245
{"changes" , 1 , exqlite_changes , ERL_NIF_DIRTY_JOB_IO_BOUND },
1284
1246
{"prepare" , 2 , exqlite_prepare , ERL_NIF_DIRTY_JOB_IO_BOUND },
1285
- {"bind" , 3 , exqlite_bind , ERL_NIF_DIRTY_JOB_IO_BOUND },
1247
+ {"reset" , 1 , exqlite_reset , ERL_NIF_DIRTY_JOB_CPU_BOUND },
1248
+ {"bind_parameter_count" , 1 , exqlite_bind_parameter_count },
1249
+ {"bind_text" , 3 , exqlite_bind_text },
1250
+ {"bind_blob" , 3 , exqlite_bind_blob },
1251
+ {"bind_integer" , 3 , exqlite_bind_integer },
1252
+ {"bind_float" , 3 , exqlite_bind_float },
1253
+ {"bind_null" , 2 , exqlite_bind_null },
1286
1254
{"step" , 2 , exqlite_step , ERL_NIF_DIRTY_JOB_IO_BOUND },
1287
1255
{"multi_step" , 3 , exqlite_multi_step , ERL_NIF_DIRTY_JOB_IO_BOUND },
1288
1256
{"columns" , 2 , exqlite_columns , ERL_NIF_DIRTY_JOB_IO_BOUND },
@@ -1295,6 +1263,8 @@ static ErlNifFunc nif_funcs[] = {
1295
1263
{"set_update_hook" , 2 , exqlite_set_update_hook , ERL_NIF_DIRTY_JOB_IO_BOUND },
1296
1264
{"set_log_hook" , 1 , exqlite_set_log_hook , ERL_NIF_DIRTY_JOB_IO_BOUND },
1297
1265
{"interrupt" , 1 , exqlite_interrupt , ERL_NIF_DIRTY_JOB_IO_BOUND },
1266
+ {"errmsg" , 1 , exqlite_errmsg },
1267
+ {"errstr" , 1 , exqlite_errstr },
1298
1268
};
1299
1269
1300
1270
ERL_NIF_INIT (Elixir .Exqlite .Sqlite3NIF , nif_funcs , on_load , NULL , NULL , on_unload )
0 commit comments