@@ -22,14 +22,16 @@ type Conn struct {
2222
2323	interrupt   context.Context 
2424	pending     * Stmt 
25+ 	stmts       []* Stmt 
2526	busy        func (int ) bool 
2627	log         func (xErrorCode , string )
2728	collation   func (* Conn , string )
29+ 	wal         func (* Conn , string , int ) error 
30+ 	trace       func (TraceEvent , any , any ) error 
2831	authorizer  func (AuthorizerActionCode , string , string , string , string ) AuthorizerReturnCode 
2932	update      func (AuthorizerActionCode , string , string , int64 )
3033	commit      func () bool 
3134	rollback    func ()
32- 	wal         func (* Conn , string , int ) error 
3335	arena       arena 
3436
3537	handle  uint32 
@@ -202,6 +204,7 @@ func (c *Conn) PrepareFlags(sql string, flags PrepareFlag) (stmt *Stmt, tail str
202204	if  stmt .handle  ==  0  {
203205		return  nil , "" , nil 
204206	}
207+ 	c .stmts  =  append (c .stmts , stmt )
205208	return  stmt , tail , nil 
206209}
207210
@@ -326,7 +329,12 @@ func (c *Conn) SetInterrupt(ctx context.Context) (old context.Context) {
326329	// A busy SQL statement prevents SQLite from ignoring an interrupt 
327330	// that comes before any other statements are started. 
328331	if  c .pending  ==  nil  {
329- 		c .pending , _ , _  =  c .Prepare (`WITH RECURSIVE c(x) AS (VALUES(0) UNION ALL SELECT x FROM c) SELECT x FROM c` )
332+ 		defer  c .arena .mark ()()
333+ 		stmtPtr  :=  c .arena .new (ptrlen )
334+ 		loopPtr  :=  c .arena .string (`WITH RECURSIVE c(x) AS (VALUES(0) UNION ALL SELECT x FROM c) SELECT x FROM c` )
335+ 		c .call ("sqlite3_prepare_v3" , uint64 (c .handle ), uint64 (loopPtr ), math .MaxUint64 , 0 , uint64 (stmtPtr ), 0 )
336+ 		c .pending  =  & Stmt {c : c }
337+ 		c .pending .handle  =  util .ReadUint32 (c .mod , stmtPtr )
330338	}
331339
332340	old  =  c .interrupt 
@@ -414,10 +422,74 @@ func busyCallback(ctx context.Context, mod api.Module, pDB uint32, count int32)
414422	return  retry 
415423}
416424
425+ // Status retrieves runtime status information about a database connection. 
426+ // 
427+ // https://sqlite.org/c3ref/db_status.html 
428+ func  (c  * Conn ) Status (op  DBStatus , reset  bool ) (current , highwater  int , err  error ) {
429+ 	defer  c .arena .mark ()()
430+ 	hiPtr  :=  c .arena .new (4 )
431+ 	curPtr  :=  c .arena .new (4 )
432+ 
433+ 	var  i  uint64 
434+ 	if  reset  {
435+ 		i  =  1 
436+ 	}
437+ 
438+ 	r  :=  c .call ("sqlite3_db_status" , uint64 (c .handle ),
439+ 		uint64 (op ), uint64 (curPtr ), uint64 (hiPtr ), i )
440+ 	if  err  =  c .error (r ); err  ==  nil  {
441+ 		current  =  int (util .ReadUint32 (c .mod , curPtr ))
442+ 		highwater  =  int (util .ReadUint32 (c .mod , hiPtr ))
443+ 	}
444+ 	return 
445+ }
446+ 
447+ // TableColumnMetadata extracts metadata about a column of a table. 
448+ // 
449+ // https://sqlite.org/c3ref/table_column_metadata.html 
450+ func  (c  * Conn ) TableColumnMetadata (schema , table , column  string ) (declType , collSeq  string , notNull , primaryKey , autoInc  bool , err  error ) {
451+ 	defer  c .arena .mark ()()
452+ 
453+ 	var  schemaPtr , columnPtr  uint32 
454+ 	declTypePtr  :=  c .arena .new (ptrlen )
455+ 	collSeqPtr  :=  c .arena .new (ptrlen )
456+ 	notNullPtr  :=  c .arena .new (ptrlen )
457+ 	primaryKeyPtr  :=  c .arena .new (ptrlen )
458+ 	autoIncPtr  :=  c .arena .new (ptrlen )
459+ 	if  schema  !=  ""  {
460+ 		schemaPtr  =  c .arena .string (schema )
461+ 	}
462+ 	tablePtr  :=  c .arena .string (table )
463+ 	if  column  !=  ""  {
464+ 		columnPtr  =  c .arena .string (column )
465+ 	}
466+ 
467+ 	r  :=  c .call ("sqlite3_table_column_metadata" , uint64 (c .handle ),
468+ 		uint64 (schemaPtr ), uint64 (tablePtr ), uint64 (columnPtr ),
469+ 		uint64 (declTypePtr ), uint64 (collSeqPtr ),
470+ 		uint64 (notNullPtr ), uint64 (primaryKeyPtr ), uint64 (autoIncPtr ))
471+ 	if  err  =  c .error (r ); err  ==  nil  &&  column  !=  ""  {
472+ 		declType  =  util .ReadString (c .mod , util .ReadUint32 (c .mod , declTypePtr ), _MAX_NAME )
473+ 		collSeq  =  util .ReadString (c .mod , util .ReadUint32 (c .mod , collSeqPtr ), _MAX_NAME )
474+ 		notNull  =  util .ReadUint32 (c .mod , notNullPtr ) !=  0 
475+ 		autoInc  =  util .ReadUint32 (c .mod , autoIncPtr ) !=  0 
476+ 		primaryKey  =  util .ReadUint32 (c .mod , primaryKeyPtr ) !=  0 
477+ 	}
478+ 	return 
479+ }
480+ 
417481func  (c  * Conn ) error (rc  uint64 , sql  ... string ) error  {
418482	return  c .sqlite .error (rc , c .handle , sql ... )
419483}
420484
485+ func  (c  * Conn ) stmtsIter (yield  func (* Stmt ) bool ) {
486+ 	for  _ , s  :=  range  c .stmts  {
487+ 		if  ! yield (s ) {
488+ 			break 
489+ 		}
490+ 	}
491+ }
492+ 
421493// DriverConn is implemented by the SQLite [database/sql] driver connection. 
422494// 
423495// It can be used to access SQLite features like [online backup]. 
0 commit comments