@@ -58,111 +58,156 @@ func (s *Session) AttachSession(tableName string) error {
58
58
// Delete deletes a session object.
59
59
func (s * Session ) DeleteSession () error {
60
60
if s .session != nil {
61
- // Call sqlite3session_delete to free the session object
62
61
C .sqlite3session_delete (s .session )
63
- s .session = nil // Set session to nil to avoid double deletion
62
+ s .session = nil
64
63
}
65
64
return nil
66
65
}
67
66
67
+ // Changeset represents a changeset object.
68
68
type Changeset struct {
69
- cs []byte
69
+ b []byte
70
70
}
71
71
72
- type ChangesetIterator struct {
73
- iter * C.sqlite3_changeset_iter
74
- }
75
-
76
- // Changeset generates a changeset from a session object.
77
- func (s * Session ) Changeset () (* Changeset , error ) {
72
+ // NewChangeset returns a changeset from a session object.
73
+ func NewChangeset (s * Session ) (* Changeset , error ) {
78
74
var nChangeset C.int
79
75
var pChangeset unsafe.Pointer
80
76
81
- // Call sqlite3session_changeset
82
77
rc := C .sqlite3session_changeset (s .session , & nChangeset , & pChangeset )
83
78
if rc != C .SQLITE_OK {
84
79
return nil , fmt .Errorf ("sqlite3session_changeset: %s" , C .GoString (C .sqlite3_errstr (rc )))
85
80
}
86
- defer C .sqlite3_free (pChangeset ) // Free the changeset buffer after use
81
+ defer C .sqlite3_free (pChangeset )
87
82
88
- // copy the changeset buffer to a Go byte slice, because cgo can nuke its memory at any time
83
+ // Copy the changeset buffer to a Go byte slice, because cgo
84
+ // does not support Go slices with C memory.
89
85
changeset := C .GoBytes (pChangeset , nChangeset )
90
- return & Changeset {cs : changeset }, nil
86
+ return & Changeset {b : changeset }, nil
91
87
}
92
88
93
- // ChangesetStart creates and initializes a changeset iterator.
94
- func ChangesetStart (changeset []byte ) (* ChangesetIterator , error ) {
95
- var iter * C.sqlite3_changeset_iter
89
+ // ChangesetIterator represents a changeset iterator object.
90
+ type ChangesetIterator struct {
91
+ iter * C.sqlite3_changeset_iter
92
+ }
96
93
97
- // Call sqlite3changeset_start
98
- rc := C .sqlite3changeset_start (& iter , C .int (len (changeset )), unsafe .Pointer (& changeset [0 ]))
94
+ // NewChangesetIterator creates a new changeset iterator object.
95
+ func NewChangesetIterator (cs * Changeset ) (* ChangesetIterator , error ) {
96
+ var iter * C.sqlite3_changeset_iter
97
+ ptr := unsafe .Pointer (nil )
98
+ if len (cs .b ) > 0 {
99
+ ptr = unsafe .Pointer (& cs .b [0 ])
100
+ }
101
+ rc := C .sqlite3changeset_start (& iter , C .int (len (cs .b )), ptr )
99
102
if rc != C .SQLITE_OK {
100
103
return nil , fmt .Errorf ("sqlite3changeset_start: %s" , C .GoString (C .sqlite3_errstr (rc )))
101
104
}
102
-
103
105
return & ChangesetIterator {iter : iter }, nil
104
106
}
105
107
106
- func (cs * Changeset ) Start () (* ChangesetIterator , error ) {
107
- return ChangesetStart (cs .cs )
108
- }
109
-
110
- // ChangesetNext moves the changeset iterator to the next change.
111
- func (ci * ChangesetIterator ) ChangesetNext () (bool , error ) {
108
+ // Next moves the changeset iterator to the next change.
109
+ func (ci * ChangesetIterator ) Next () (bool , error ) {
112
110
rc := C .sqlite3changeset_next (ci .iter )
113
111
if rc == C .SQLITE_DONE {
114
112
return false , nil // No more changes
115
113
}
116
- if rc != C .SQLITE_OK {
114
+ if rc != C .SQLITE_ROW {
117
115
return false , fmt .Errorf ("sqlite3changeset_next: %s" , C .GoString (C .sqlite3_errstr (rc )))
118
116
}
119
117
return true , nil
120
118
}
121
119
122
- // ChangesetOp returns the type of change (INSERT, UPDATE, or DELETE) that the iterator points to.
123
- func (ci * ChangesetIterator ) ChangesetOp () (string , int , int , bool , error ) {
120
+ // Op returns the current Operation from a Changeset Iterator
121
+ func (ci * ChangesetIterator ) Op () (tblName string , numCol int , oper int , indirect bool , err error ) {
124
122
var tableName * C.char
125
123
var nCol C.int
126
124
var op C.int
127
- var indirect C.int
125
+ var ind C.int
128
126
129
- rc := C .sqlite3changeset_op (ci .iter , & tableName , & nCol , & op , & indirect )
127
+ rc := C .sqlite3changeset_op (ci .iter , & tableName , & nCol , & op , & ind )
130
128
if rc != C .SQLITE_OK {
131
129
return "" , 0 , 0 , false , fmt .Errorf ("sqlite3changeset_op: %s" , C .GoString (C .sqlite3_errstr (rc )))
132
130
}
133
-
134
- return C .GoString (tableName ), int (nCol ), int (op ), indirect != 0 , nil
131
+ return C .GoString (tableName ), int (nCol ), int (op ), ind != 0 , nil
135
132
}
136
133
137
- // ChangesetOld retrieves the old value for the specified column in the change payload.
138
- func (ci * ChangesetIterator ) ChangesetOld (column int ) (* C.sqlite3_value , error ) {
139
- var value * C.sqlite3_value
134
+ // Old retrieves the old value for the specified column in the change payload.
135
+ func (ci * ChangesetIterator ) Old (dest []any ) error {
136
+ for i := 0 ; i < len (dest ); i ++ {
137
+ var val * C.sqlite3_value
138
+ var src any
140
139
141
- rc := C .sqlite3changeset_old (ci .iter , C .int (column ), & value )
142
- if rc != C .SQLITE_OK {
143
- return nil , fmt .Errorf ("sqlite3changeset_old: %s" , C .GoString (C .sqlite3_errstr (rc )))
144
- }
140
+ rc := C .sqlite3changeset_old (ci .iter , C .int (i ), & val )
141
+ if rc != C .SQLITE_OK {
142
+ return fmt .Errorf ("sqlite3changeset_old: %s" , C .GoString (C .sqlite3_errstr (rc )))
143
+ }
144
+
145
+ switch C .sqlite3_value_type (val ) {
146
+ case C .SQLITE_INTEGER :
147
+ src = int64 (C .sqlite3_value_int64 (val ))
148
+ case C .SQLITE_FLOAT :
149
+ src = float64 (C .sqlite3_value_double (val ))
150
+ case C .SQLITE_BLOB :
151
+ len := C .sqlite3_value_bytes (val )
152
+ blobptr := C .sqlite3_value_blob (val )
153
+ src = C .GoBytes (blobptr , len )
154
+ case C .SQLITE_TEXT :
155
+ len := C .sqlite3_value_bytes (val )
156
+ cstrptr := unsafe .Pointer (C .sqlite3_value_text (val ))
157
+ src = C .GoBytes (cstrptr , len )
158
+ case C .SQLITE_NULL :
159
+ src = nil
160
+ }
145
161
146
- return value , nil
162
+ err := convertAssign (& dest [i ], src )
163
+ if err != nil {
164
+ return err
165
+ }
166
+ }
167
+ return nil
147
168
}
148
169
149
- // ChangesetNew retrieves the new value for the specified column in the change payload.
150
- func (ci * ChangesetIterator ) ChangesetNew (column int ) (* C.sqlite3_value , error ) {
151
- var value * C.sqlite3_value
170
+ // New retrieves the new value for the specified column in the change payload.
171
+ func (ci * ChangesetIterator ) New (dest []any ) error {
172
+ for i := 0 ; i < len (dest ); i ++ {
173
+ var val * C.sqlite3_value
174
+ var src any
152
175
153
- rc := C .sqlite3changeset_new (ci .iter , C .int (column ), & value )
154
- if rc != C .SQLITE_OK {
155
- return nil , fmt .Errorf ("sqlite3changeset_new: %s" , C .GoString (C .sqlite3_errstr (rc )))
156
- }
176
+ rc := C .sqlite3changeset_new (ci .iter , C .int (i ), & val )
177
+ if rc != C .SQLITE_OK {
178
+ return fmt .Errorf ("sqlite3changeset_new: %s" , C .GoString (C .sqlite3_errstr (rc )))
179
+ }
180
+
181
+ switch C .sqlite3_value_type (val ) {
182
+ case C .SQLITE_INTEGER :
183
+ src = int64 (C .sqlite3_value_int64 (val ))
184
+ case C .SQLITE_FLOAT :
185
+ src = float64 (C .sqlite3_value_double (val ))
186
+ case C .SQLITE_BLOB :
187
+ len := C .sqlite3_value_bytes (val )
188
+ blobptr := C .sqlite3_value_blob (val )
189
+ src = C .GoBytes (blobptr , len )
190
+ case C .SQLITE_TEXT :
191
+ len := C .sqlite3_value_bytes (val )
192
+ cstrptr := unsafe .Pointer (C .sqlite3_value_text (val ))
193
+ src = C .GoBytes (cstrptr , len )
194
+ case C .SQLITE_NULL :
195
+ src = nil
196
+ }
157
197
158
- return value , nil
198
+ err := convertAssign (& dest [i ], src )
199
+ if err != nil {
200
+ return err
201
+ }
202
+ }
203
+ return nil
159
204
}
160
205
161
- // ChangesetFinalize deletes a changeset iterator.
162
- func (ci * ChangesetIterator ) ChangesetFinalize () error {
206
+ // Finalize deletes a changeset iterator.
207
+ func (ci * ChangesetIterator ) Finalize () error {
163
208
if ci .iter != nil {
164
209
rc := C .sqlite3changeset_finalize (ci .iter )
165
- ci .iter = nil // Prevent double finalization
210
+ ci .iter = nil
166
211
if rc != C .SQLITE_OK {
167
212
return fmt .Errorf ("sqlite3changeset_finalize: %s" , C .GoString (C .sqlite3_errstr (rc )))
168
213
}
0 commit comments