@@ -62,6 +62,21 @@ func init() {
6262 })
6363}
6464
65+ type intStack struct {
66+ s []int
67+ }
68+
69+ func (s * intStack ) Push (n int ) { s .s = append (s .s , n ) }
70+
71+ func (s * intStack ) Pop () (int , bool ) {
72+ if len (s .s ) == 0 {
73+ return 0 , false
74+ }
75+ var n int
76+ n , s .s = s .s [0 ], s .s [1 :]
77+ return n , true
78+ }
79+
6580const sqlite3HeaderSize = 100
6681
6782const (
@@ -106,12 +121,14 @@ var serialTypeMapper = scalar.Fn(func(s scalar.S) (scalar.S, error) {
106121 return s , nil
107122})
108123
124+ type pageType int
125+
109126const (
110- pageTypePtrmap = 0x00
111- pageTypeBTreeIndexInterior = 0x02
112- pageTypeBTreeTableInterior = 0x05
113- pageTypeBTreeIndexLeaf = 0x0a
114- pageTypeBTreeTableLeaf = 0x0d
127+ pageTypePtrmap pageType = 0x00
128+ pageTypeBTreeIndexInterior = 0x02
129+ pageTypeBTreeTableInterior = 0x05
130+ pageTypeBTreeIndexLeaf = 0x0a
131+ pageTypeBTreeTableLeaf = 0x0d
115132)
116133
117134var pageTypeMap = scalar.UToSymStr {
@@ -299,6 +316,14 @@ func sqlite3DecodeTreePage(d *decode.D, h sqlite3Header, x int64, payLoadLen int
299316 }
300317}
301318
319+ func sqlite3SeekPage (d * decode.D , h sqlite3Header , i int ) {
320+ pageOffset := h .pageSize * int64 (i )
321+ if i == 0 {
322+ pageOffset += sqlite3HeaderSize
323+ }
324+ d .SeekAbs (pageOffset * 8 )
325+ }
326+
302327func sqlite3Decode (d * decode.D , in interface {}) interface {} {
303328 var h sqlite3Header
304329
@@ -340,6 +365,49 @@ func sqlite3Decode(d *decode.D, in interface{}) interface{} {
340365 }
341366 })
342367
368+ // pageTypes := map[int]pageType{}
369+ // pageVisitStack := &intStack{}
370+ // pageVisitStack.Push(0)
371+
372+ // for {
373+ // i, ok := pageVisitStack.Pop()
374+ // if !ok {
375+ // break
376+ // }
377+ // if _, ok := pageTypes[i]; ok {
378+ // d.Fatalf("page %d already visited", i)
379+ // }
380+
381+ // sqlite3SeekPage(d, h, i)
382+ // typ := d.U8()
383+
384+ // switch typ {
385+ // case pageTypeBTreeIndexInterior,
386+ // pageTypeBTreeTableInterior:
387+
388+ // d.U16() // start_free_blocks
389+ // d.U16() // cell_start
390+ // d.U8() // cell_fragments
391+ // rightPointer := d.U32()
392+
393+ // pageCells := d.U16()
394+ // for i := uint64(0); i < pageCells; i++ {
395+
396+ // }
397+
398+ // switch typ {
399+ // case pageTypeBTreeIndexInterior:
400+
401+ // }
402+
403+ // default:
404+ // d.Fatalf("asd")
405+ // }
406+
407+ // }
408+
409+ // return nil
410+
343411 d .FieldArray ("pages" , func (d * decode.D ) {
344412 d .RangeSorted = false
345413
@@ -348,13 +416,24 @@ func sqlite3Decode(d *decode.D, in interface{}) interface{} {
348416 d .FieldValueStr ("type" , "page0_index_fill" )
349417 })
350418
419+ // for {
420+ // i, ok := pageStack.Pop()
421+ // if !ok {
422+ // break
423+ // }
424+ // if _, ok := pageSeen[i]; ok {
425+ // d.Fatalf("page %d already visited", i)
426+ // }
427+ // pageSeen[i] = struct{}{}
428+
351429 for i := 0 ; i < h .databaseSizePages ; i ++ {
352430 pageOffset := h .pageSize * int64 (i )
353431 d .SeekAbs (pageOffset * 8 )
354432 // skip header for first page
355433 if i == 0 {
356434 d .SeekRel (sqlite3HeaderSize * 8 )
357435 }
436+ sqlite3SeekPage (d , h , i )
358437
359438 d .FieldStruct ("page" , func (d * decode.D ) {
360439 typ := d .FieldU8 ("type" , pageTypeMap )
0 commit comments