Class: Amalgalite::SQLite3::Database

Inherits:
Object
  • Object
show all
Defined in:
ext/amalgalite/c/amalgalite_database.c,
lib/amalgalite/sqlite3/database/status.rb,
lib/amalgalite/sqlite3/database/function.rb,
ext/amalgalite/c/amalgalite_database.c

Overview

The ruby extension wrapper around the core sqlite3 database object.

Defined Under Namespace

Classes: DBStatus, Function, Stat

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.open(*args) ⇒ Object

call-seq:

Amalgalite::SQLite3::Database.open( filename, flags = READWRITE | CREATE ) -> Database

Create a new SQLite2 database with a UTF-8 encoding.



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
# File 'ext/amalgalite/c/amalgalite_database.c', line 21

VALUE am_sqlite3_database_open(int argc, VALUE *argv, VALUE class)
{
    VALUE  self = am_sqlite3_database_alloc(class);
    VALUE  rFlags;
    VALUE  rFilename;
    int     flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
    char*   filename;
    int     rc;
    am_sqlite3* am_db;

    /* at least a filename argument is required */
    rb_scan_args( argc, argv, "11", &rFilename, &rFlags );

    /* convert flags to the sqlite version */
    flags  = ( Qnil == rFlags ) ? flags : FIX2INT(rFlags);
    filename = StringValuePtr(rFilename);

    /* extract the sqlite3 wrapper struct */
    Data_Get_Struct(self, am_sqlite3, am_db);

    /* open the sqlite3 database */
    rc = sqlite3_open_v2( filename, &(am_db->db), flags, 0);
    if ( SQLITE_OK != rc ) {
        rb_raise(eAS_Error, "Failure to open database %s : [SQLITE_ERROR %d] : %s\n",
                filename, rc, sqlite3_errmsg(am_db->db));
    }

    /* by default turn on the extended result codes */
    rc = sqlite3_extended_result_codes( am_db->db, 1);
    if ( SQLITE_OK != rc ) {
        rb_raise(eAS_Error, "Failure to set extended result codes %s : [SQLITE_ERROR %d] : %s\n",
                filename, rc, sqlite3_errmsg(am_db->db));
    }

    return self;
}

.Amalgalite::SQLite3::Database.open16(filename) ⇒ SQLite3::Database

Create a new SQLite3 database with a UTF-16 encoding

Returns:



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'ext/amalgalite/c/amalgalite_database.c', line 65

VALUE am_sqlite3_database_open16(VALUE class, VALUE rFilename)
{
    VALUE       self = am_sqlite3_database_alloc(class);
    char*       filename = StringValuePtr(rFilename);
    am_sqlite3* am_db;
    int         rc;

    Data_Get_Struct(self, am_sqlite3, am_db);
    rc = sqlite3_open16( filename, &(am_db->db) );
    if ( SQLITE_OK != rc ) {
        rb_raise(eAS_Error, "Failure to open UTF-16 database %s : [SQLITE_ERROR %d] : %s\n",
                filename, rc, sqlite3_errmsg( am_db->db ));
    }

    /* by default turn on the extended result codes */
    rc = sqlite3_extended_result_codes( am_db->db, 1);
    if ( SQLITE_OK != rc ) {
        rb_raise(eAS_Error, "Failure to set extended result codes on UTF-16 database %s : [SQLITE_ERROR %d] : %s\n",
                filename, rc, (char*)sqlite3_errmsg16(am_db->db));
    }

    return self;
}

Instance Method Details

#autocommit?Boolean

return true if the database is in autocommit mode, otherwise return false

Returns:



137
138
139
140
141
142
143
144
145
146
# File 'ext/amalgalite/c/amalgalite_database.c', line 137

VALUE am_sqlite3_database_is_autocommit(VALUE self)
{
    am_sqlite3   *am_db;
    int           rc;

    Data_Get_Struct(self, am_sqlite3, am_db);
    rc = sqlite3_get_autocommit( am_db->db );

    return ( 0 == rc ) ? Qfalse : Qtrue ;
}

#busy_handler(proc_like) ⇒ Object

register a busy handler. If the argument is nil, then an existing busy handler is removed. Otherwise the argument is registered as the busy handler.



539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
# File 'ext/amalgalite/c/amalgalite_database.c', line 539

VALUE am_sqlite3_database_busy_handler( VALUE self, VALUE handler )
{
    am_sqlite3   *am_db;
    int           rc;

    Data_Get_Struct(self, am_sqlite3, am_db);

    /* Removing a busy handler case, remove it from sqlite and then remove it
     * from the garbage collector if it existed */
    if ( Qnil == handler ) {
        rc = sqlite3_busy_handler( am_db->db, NULL, NULL );
        if ( SQLITE_OK != rc ) {
            rb_raise(eAS_Error, "Failure removing busy handler : [SQLITE_ERROR %d] : %s\n", 
                    rc, sqlite3_errmsg( am_db->db ));
        }
        if ( Qnil != am_db->busy_handler_obj ) {
            rb_gc_unregister_address( &(am_db->busy_handler_obj) );
        }
    } else {
        /* installing a busy handler
         * - register it with sqlite
         * - keep a reference for ourselves with our database handle
         * - registere the handler reference with the garbage collector
         */
        rc = sqlite3_busy_handler( am_db->db, amalgalite_xBusy, (void*)handler );
        if ( SQLITE_OK != rc ) {
            rb_raise(eAS_Error, "Failure setting busy handler : [SQLITE_ERROR %d] : %s\n", 
                    rc, sqlite3_errmsg( am_db->db ));
        }
        am_db->busy_handler_obj = handler;
        rb_gc_register_address( &(am_db->busy_handler_obj) );
    }
    return Qnil;
}

#closeObject

Close the database



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'ext/amalgalite/c/amalgalite_database.c', line 95

VALUE am_sqlite3_database_close(VALUE self)
{
    am_sqlite3   *am_db;
    int           rc = 0;

    Data_Get_Struct(self, am_sqlite3, am_db);
    rc = sqlite3_close( am_db->db );
    am_db->db = NULL;
    if ( SQLITE_OK != rc ) {
        rb_raise(eAS_Error, "Failure to close database : [SQLITE_ERROR %d] : %s\n",
                rc, sqlite3_errmsg( am_db->db ));
    }

    return self;

}

#define_aggregate(name, arity, klass) ⇒ Object

register the given klass to be invoked as an sql aggregate.



898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
# File 'ext/amalgalite/c/amalgalite_database.c', line 898

VALUE am_sqlite3_database_define_aggregate( VALUE self, VALUE name, VALUE arity, VALUE klass )
{
    am_sqlite3   *am_db;
    int           rc;
    char*         zFunctionName = RSTRING_PTR(name);
    int           nArg = FIX2INT( arity );

    Data_Get_Struct(self, am_sqlite3, am_db);
    rc = sqlite3_create_function( am_db->db,
                                  zFunctionName, nArg,
                                  SQLITE_UTF8,
                                  (void *)klass,
                                  NULL, /* for scalar functions, not used here */
                                  amalgalite_xStep,
                                  amalgalite_xFinal);
    if ( SQLITE_OK != rc ) {
        /* in the case of SQLITE_MISUSE the error message in the database may
         * not be set.  In this case, hardcode the error. 
         * http://sqlite.org/c3ref/errcode.html
         *
         * This is a result of 3.6.15 which has sqlite3_create_function return
         * SQLITE_MISUSE intead of SQLITE_ERROR if called with incorrect
         * parameters.
         */
       if ( SQLITE_MISUSE == rc ) { 
         rb_raise(eAS_Error, "Failure defining SQL function '%s' with arity '%d' : [SQLITE_ERROR %d] : Library used incorrectly\n",
                zFunctionName, nArg, rc);
       } else {
         rb_raise(eAS_Error, "Failure defining SQL function '%s' with arity '%d' : [SQLITE_ERROR %d] : %s\n",
                zFunctionName, nArg, rc, sqlite3_errmsg( am_db->db ));
       }
    }
    rb_gc_register_address( &klass );
    return Qnil;
}

#define_function(name, proc_like) ⇒ Object

register the given function to be invoked as an sql function.



684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
# File 'ext/amalgalite/c/amalgalite_database.c', line 684

VALUE am_sqlite3_database_define_function( VALUE self, VALUE name, VALUE proc_like )
{
    am_sqlite3   *am_db;
    int           rc;
    VALUE         arity = rb_funcall( proc_like, rb_intern( "arity" ), 0 );
    char*         zFunctionName = RSTRING_PTR(name);
    int           nArg = FIX2INT( arity );

    Data_Get_Struct(self, am_sqlite3, am_db);
    rc = sqlite3_create_function( am_db->db,
                                  zFunctionName, nArg,
                                  SQLITE_UTF8,
                                  (void *)proc_like, amalgalite_xFunc,
                                  NULL, NULL);
    if ( SQLITE_OK != rc ) {
        /* in the case of SQLITE_MISUSE the error message in the database may
         * not be set.  In this case, hardcode the error. 
         * http://sqlite.org/c3ref/errcode.html
         *
         * This is a result of 3.6.15 which has sqlite3_create_function return
         * SQLITE_MISUSE intead of SQLITE_ERROR if called with incorrect
         * parameters.
         */
       if ( SQLITE_MISUSE == rc ) { 
         rb_raise(eAS_Error, "Failure defining SQL function '%s' with arity '%d' : [SQLITE_ERROR %d] : Library used incorrectly\n",
                zFunctionName, nArg, rc);
       } else {
         rb_raise(eAS_Error, "Failure defining SQL function '%s' with arity '%d' : [SQLITE_ERROR %d] : %s\n",
                zFunctionName, nArg, rc, sqlite3_errmsg( am_db->db ));
       }
    }
    rb_gc_register_address( &proc_like );
    return Qnil;
}

#execute_batch(rSQL) ⇒ Object

call-seqL

database.execute_batch( sqls ) -> Boolean

Execute the statements in a batch.



310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
# File 'ext/amalgalite/c/amalgalite_database.c', line 310

VALUE am_sqlite3_database_exec(VALUE self, VALUE rSQL)
{
  VALUE        sql = StringValue( rSQL );
  am_sqlite3  *am_db;
  int          rc;

  Data_Get_Struct(self, am_sqlite3, am_db);
  
  rc = sqlite3_exec( am_db->db, RSTRING_PTR(sql), NULL, NULL, NULL );

  if ( SQLITE_OK != rc ){
    rb_raise( eAS_Error, "Failed to execute bulk statements: [SQLITE_ERROR %d] : %s\n",
	      rc, sqlite3_errmsg(am_db->db));
  }

  /* Presume that nobody will want to batch execute
     more than a Fixnum's worth of statements */
  return Qtrue;
}

#interrupt!Object

Cause another thread with a handle on this database to be interrupted and return at the earliest opportunity as interrupted.



971
972
973
974
975
976
977
978
# File 'ext/amalgalite/c/amalgalite_database.c', line 971

VALUE am_sqlite3_database_interrupt_bang( VALUE self )
{
    am_sqlite3  *am_db;

    Data_Get_Struct(self, am_sqlite3, am_db);
    sqlite3_interrupt( am_db->db );
    return Qnil;
}

#last_error_codeInteger

return the last error code that happened in the database

Returns:

  • (Integer)


174
175
176
177
178
179
180
181
182
183
# File 'ext/amalgalite/c/amalgalite_database.c', line 174

VALUE am_sqlite3_database_last_error_code(VALUE self)
{
    am_sqlite3   *am_db;
    int           code;

    Data_Get_Struct(self, am_sqlite3, am_db);
    code = sqlite3_errcode( am_db->db );

    return INT2FIX( code );
}

#last_error_messageString

return the last error message that happened in the database

Returns:

  • (String)


192
193
194
195
196
197
198
199
200
201
# File 'ext/amalgalite/c/amalgalite_database.c', line 192

VALUE am_sqlite3_database_last_error_message(VALUE self)
{
    am_sqlite3   *am_db;
    const char   *message;

    Data_Get_Struct(self, am_sqlite3, am_db);
    message = sqlite3_errmsg( am_db->db );

    return rb_str_new2( message );
}

#last_insert_rowidInteger

Return the rowid of the last row inserted into the database from this database connection.

Returns:

  • (Integer)


119
120
121
122
123
124
125
126
127
128
# File 'ext/amalgalite/c/amalgalite_database.c', line 119

VALUE am_sqlite3_database_last_insert_rowid(VALUE self)
{
    am_sqlite3   *am_db;
    sqlite3_int64 last_id;

    Data_Get_Struct(self, am_sqlite3, am_db);
    last_id = sqlite3_last_insert_rowid( am_db->db );

    return SQLINT64_2NUM( last_id );
}

#prepare(sql) ⇒ SQLite3::Statement

Create a new SQLite3 statement.

Returns:



273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
# File 'ext/amalgalite/c/amalgalite_database.c', line 273

VALUE am_sqlite3_database_prepare(VALUE self, VALUE rSQL)
{
    VALUE            sql = StringValue( rSQL );
    VALUE            stmt = am_sqlite3_statement_alloc(cAS_Statement);
    am_sqlite3      *am_db;
    am_sqlite3_stmt *am_stmt;
    const char      *tail;
    int              rc;

    Data_Get_Struct(self, am_sqlite3, am_db);

    Data_Get_Struct(stmt, am_sqlite3_stmt, am_stmt);
    rc = sqlite3_prepare_v2( am_db->db, RSTRING_PTR(sql), (int)RSTRING_LEN(sql),
                            &(am_stmt->stmt), &tail);
    if ( SQLITE_OK != rc) {
        rb_raise(eAS_Error, "Failure to prepare statement %s : [SQLITE_ERROR %d] : %s\n",
                RSTRING_PTR(sql), rc, sqlite3_errmsg(am_db->db));
        am_sqlite3_statement_free( am_stmt );
    }

    if ( tail != NULL ) {
        am_stmt->remaining_sql = rb_str_new2( tail );
        rb_gc_register_address( &(am_stmt->remaining_sql) );
    } else {
        am_stmt->remaining_sql = Qnil;
    }

    return stmt;
}

#progress_handler(op_count, proc_like) ⇒ Object

register a progress handler. If the argument is nil, then an existing progress handler is removed. Otherwise the argument is registered as the progress handler.



610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
# File 'ext/amalgalite/c/amalgalite_database.c', line 610

VALUE am_sqlite3_database_progress_handler( VALUE self, VALUE op_count, VALUE handler )
{
    am_sqlite3   *am_db;

    Data_Get_Struct(self, am_sqlite3, am_db);

    /* Removing a progress handler, remove it from sqlite and then remove it
     * from the garbage collector if it existed */
    if ( Qnil == handler ) {
        sqlite3_progress_handler( am_db->db, -1, NULL, (void*)NULL );
        if ( Qnil != am_db->progress_handler_obj ) {
            rb_gc_unregister_address( &(am_db->progress_handler_obj) );
        }
    } else {
        int  op_codes = FIX2INT( op_count );
        /* installing a progress handler
         * - register it with sqlite
         * - keep a reference for ourselves with our database handle
         * - register the handler reference with the garbage collector
         */
        sqlite3_progress_handler( am_db->db, op_codes, amalgalite_xProgress, (void*)handler );
        am_db->progress_handler_obj = handler;
        rb_gc_register_address( &(am_db->progress_handler_obj) );
    }
    return Qnil;
}

#register_trace_tap(tap_obj) ⇒ Object

This registers an object to be called for all the trace objects in the sqlite system. From an SQLite perspective, the trace object is registered for both SQLITE_TRACE_STMT and SQLITE_TRACE_PROFILE.

The object must respond to both ‘trace` and `profile` methods. See

Amalgalite::Trace

This is an experimental api and is subject to change, or removal.



400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
# File 'ext/amalgalite/c/amalgalite_database.c', line 400

VALUE am_sqlite3_database_register_trace_tap(VALUE self, VALUE tap )
{
    am_sqlite3   *am_db;

    Data_Get_Struct(self, am_sqlite3, am_db);

    /* Qnil, unregister the item and tell the garbage collector we are done with
     * it.
     */
    if ( Qnil == tap ) {

        sqlite3_trace_v2( am_db->db, 0, NULL, NULL );
        rb_gc_unregister_address( &(am_db->trace_obj) );
        am_db->trace_obj = Qnil;

    /* register the item and store the reference to the object in the am_db
     * structure.  We also have to tell the Ruby garbage collector that we
     * point to the Ruby object from C.
     */
    } else {

        am_db->trace_obj = tap;
        rb_gc_register_address( &(am_db->trace_obj) );
        sqlite3_trace_v2( am_db->db, SQLITE_TRACE_STMT | SQLITE_TRACE_PROFILE, amalgalite_xTraceCallback, (void *)am_db->trace_obj );
    }

    return Qnil;
}

#remove_aggregate(name, arity, klass) ⇒ Object

remove the given klass from availability in SQL as an aggregate.



941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
# File 'ext/amalgalite/c/amalgalite_database.c', line 941

VALUE am_sqlite3_database_remove_aggregate( VALUE self, VALUE name, VALUE arity, VALUE klass )
{
    am_sqlite3    *am_db;
    int            rc;
    char*         zFunctionName = RSTRING_PTR(name);
    int           nArg = FIX2INT( arity );

    Data_Get_Struct(self, am_sqlite3, am_db);
    rc = sqlite3_create_function( am_db->db, 
                                  zFunctionName, nArg,
                                  SQLITE_UTF8,
                                  NULL, NULL,
                                  NULL, 
                                  NULL);
    if ( SQLITE_OK != rc ) {
       rb_raise(eAS_Error, "Failure removing SQL aggregate '%s' with arity '%d' : [SQLITE_ERROR %d] : %s\n",
                zFunctionName, nArg, rc, sqlite3_errmsg( am_db->db ));
    }
    rb_gc_unregister_address( &klass );
    return Qnil;
}

#remove_function(name, proc_like) ⇒ Object

remove the given function from availability in SQL.



725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
# File 'ext/amalgalite/c/amalgalite_database.c', line 725

VALUE am_sqlite3_database_remove_function( VALUE self, VALUE name, VALUE proc_like )
{
    am_sqlite3    *am_db;
    int            rc;
    VALUE         arity = rb_funcall( proc_like, rb_intern( "arity" ), 0 );
    char*         zFunctionName = RSTRING_PTR(name);
    int           nArg = FIX2INT( arity );

    Data_Get_Struct(self, am_sqlite3, am_db);
    rc = sqlite3_create_function( am_db->db,
                                  zFunctionName, nArg,
                                  SQLITE_UTF8,
                                  NULL, NULL,
                                  NULL, NULL);
    if ( SQLITE_OK != rc ) {
       rb_raise(eAS_Error, "Failure removing SQL function '%s' with arity '%d' : [SQLITE_ERROR %d] : %s\n",
                zFunctionName, nArg, rc, sqlite3_errmsg( am_db->db ));
    }
    rb_gc_unregister_address( &proc_like );
    return Qnil;
}

#replicate_to(other_db) ⇒ Object

Replicates the current database to the database passed in using the sqlite3_backup api



988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
# File 'ext/amalgalite/c/amalgalite_database.c', line 988

VALUE am_sqlite3_database_replicate_to( VALUE self, VALUE other )
{
    am_sqlite3  *am_src_db;
    am_sqlite3  *am_dest_db;

    sqlite3_backup *backup;
    sqlite3        *src;
    sqlite3        *dest;

    int             rc_s;
    int             rc_f;

    /* source database */
    Data_Get_Struct(self, am_sqlite3, am_src_db);
    src = am_src_db->db;

    /* destination database */
    Data_Get_Struct(other, am_sqlite3, am_dest_db);
    dest = am_dest_db->db;

    backup = sqlite3_backup_init( dest, "main", src, "main" );
    if ( NULL == backup ) {
        rb_raise(eAS_Error, "Failure to initialize replication:  [SQLITE_ERROR %d] : %s\n",
                 sqlite3_errcode( dest ), sqlite3_errmsg( dest ));
    }

    rc_s = sqlite3_backup_step( backup, -1 ); /* copy the whole thing at once */
    rc_f = sqlite3_backup_finish( backup ); 

    /* report the rc_s error if that one is bad, 
     * else raise the rc_f error, or nothing */
    if ( SQLITE_DONE != rc_s ) {
        rb_raise(eAS_Error, "Failure in replication : [SQLITE_ERROR %d] : %s\n",
                sqlite3_errcode( dest ), sqlite3_errmsg( dest ) );
    } else if ( SQLITE_OK != rc_f ) {
        rb_raise(eAS_Error, "Failure in finishing replication: [SQLITE_ERROR %d] : %s\n",
                sqlite3_errcode( dest ), sqlite3_errmsg( dest ) );
    } 

    return other;
}

#row_changesInteger

return the number of rows changed with the most recent INSERT, UPDATE or DELETE statement.

Returns:

  • (Integer)


156
157
158
159
160
161
162
163
164
165
# File 'ext/amalgalite/c/amalgalite_database.c', line 156

VALUE am_sqlite3_database_row_changes(VALUE self)
{
    am_sqlite3   *am_db;
    int           rc;

    Data_Get_Struct(self, am_sqlite3, am_db);
    rc = sqlite3_changes( am_db->db );

    return INT2FIX(rc);
}

#statusObject

return the DBstatus object for the sqlite database



64
65
66
# File 'lib/amalgalite/sqlite3/database/status.rb', line 64

def status
  @status ||= DBStatus.new( self )
end

#table_column_metadata(db_name, table_name, column_name) ⇒ Hash

Returns a hash containing the meta information about the column. The available keys are:

declared_data_type

the declared data type of the column

collation_sequence_name

the name of the collation sequence for the column

not_null_constraint

True if the column has a NOT NULL constraint

primary_key

True if the column is part of a primary key

auto_increment

True if the column is AUTO INCREMENT

Returns:

  • (Hash)


1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
# File 'ext/amalgalite/c/amalgalite_database.c', line 1044

VALUE am_sqlite3_database_table_column_metadata(VALUE self, VALUE db_name, VALUE tbl_name, VALUE col_name)
{
    am_sqlite3  *am_db;
    int         rc;

    /* input */
    const char  *zDbName      = StringValuePtr( db_name );
    const char  *zTableName   = StringValuePtr( tbl_name );
    const char  *zColumnName  = StringValuePtr( col_name );

    /* output */
    const char *pzDataType = NULL;
    const char *pzCollSeq  = NULL;
    int         pNotNull, pPrimaryKey, pAutoinc;
    VALUE       rHash      = rb_hash_new();
    VALUE       rStr       = Qnil;

    Data_Get_Struct(self, am_sqlite3, am_db);

    rc = sqlite3_table_column_metadata( am_db->db,
                                        zDbName, zTableName, zColumnName,
                                        &pzDataType, &pzCollSeq,
                                        &pNotNull, &pPrimaryKey, &pAutoinc);
    if ( SQLITE_OK != rc ) {
       rb_raise(eAS_Error, "Failure retrieveing column meta data for table '%s' column '%s' : [SQLITE_ERROR %d] : %s\n",
                zTableName, zColumnName, rc, sqlite3_errmsg( am_db-> db ));

    }

    rStr = ( NULL == pzDataType) ? Qnil : rb_str_new2( pzDataType );
    rb_hash_aset( rHash, rb_str_new2("declared_data_type"), rStr );

    rStr = ( NULL == pzCollSeq) ? Qnil : rb_str_new2( pzCollSeq );
    rb_hash_aset( rHash, rb_str_new2("collation_sequence_name"), rStr );

    rb_hash_aset( rHash, rb_str_new2("not_null_constraint"),     ( pNotNull    ? Qtrue : Qfalse ));
    rb_hash_aset( rHash, rb_str_new2("primary_key"),             ( pPrimaryKey ? Qtrue : Qfalse ));
    rb_hash_aset( rHash, rb_str_new2("auto_increment"),          ( pAutoinc   ? Qtrue : Qfalse ));

    return rHash;
}

#total_changesInteger

return the number of rows changed by INSERT, UPDATE or DELETE statements in the database connection since the connection was opened.

Returns:

  • (Integer)


211
212
213
214
215
216
217
218
219
220
# File 'ext/amalgalite/c/amalgalite_database.c', line 211

VALUE am_sqlite3_database_total_changes(VALUE self)
{
    am_sqlite3   *am_db;
    int           rc;

    Data_Get_Struct(self, am_sqlite3, am_db);
    rc = sqlite3_total_changes( am_db->db );

    return INT2FIX(rc);
}