github.com/runner-mei/ql@v1.1.0/storage.go (about) 1 // Copyright (c) 2014 ql Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package ql 6 7 import ( 8 "fmt" 9 "strings" 10 ) 11 12 type storage interface { 13 Acid() bool 14 BeginTransaction() error 15 Close() error 16 Commit() error 17 Create(data ...interface{}) (h int64, err error) 18 CreateIndex(unique bool) (handle int64, x btreeIndex, err error) 19 CreateTemp(asc bool) (bt temp, err error) 20 Delete(h int64, blobCols ...*col) error //LATER split the nil blobCols case 21 ID() (id int64, err error) 22 Name() string 23 OpenIndex(unique bool, handle int64) (btreeIndex, error) // Never called on the memory backend. 24 Read(dst []interface{}, h int64, cols ...*col) (data []interface{}, err error) 25 ResetID() (err error) 26 Rollback() error 27 Update(h int64, data ...interface{}) error 28 UpdateRow(h int64, blobCols []*col, data ...interface{}) error 29 Verify() (allocs int64, err error) 30 } 31 32 type btreeIterator interface { 33 Next() (k, v []interface{}, err error) 34 } 35 36 type temp interface { 37 BeginTransaction() error 38 Create(data ...interface{}) (h int64, err error) 39 Drop() (err error) 40 Get(k []interface{}) (v []interface{}, err error) 41 Read(dst []interface{}, h int64, cols ...*col) (data []interface{}, err error) 42 SeekFirst() (e btreeIterator, err error) 43 Set(k, v []interface{}) (err error) 44 } 45 46 type indexIterator interface { 47 Next() (k []interface{}, h int64, err error) 48 Prev() (k []interface{}, h int64, err error) 49 } 50 51 type btreeIndex interface { 52 Clear() error // supports truncate table statement 53 Create(indexedValues []interface{}, h int64) error // supports insert into statement 54 Delete(indexedValues []interface{}, h int64) error // supports delete from statement 55 Drop() error // supports drop table, drop index statements 56 Seek(indexedValues []interface{}) (iter indexIterator, hit bool, err error) // supports where clause 57 SeekFirst() (iter indexIterator, err error) // supports aggregate min / ascending order by 58 SeekLast() (iter indexIterator, err error) // supports aggregate max / descending order by 59 } 60 61 type indexedCol struct { // Column name or id() index. 62 name string 63 unique bool 64 x btreeIndex 65 xroot int64 66 } 67 68 type index2 struct { // Expression list index. 69 unique bool 70 x btreeIndex 71 xroot int64 72 sources []string 73 exprList []expression 74 } 75 76 func (x *index2) eval(ctx *execCtx, cols []*col, id int64, r []interface{}) ([]interface{}, error) { 77 f, isFile := ctx.db.store.(*file) 78 vlist := make([]interface{}, len(x.exprList)) 79 m := map[interface{}]interface{}{"$id": id} 80 for _, col := range cols { 81 ci := col.index 82 v := interface{}(nil) 83 if ci < len(r) { 84 v = r[ci] 85 } 86 if b, ok := v.([]byte); ok && isFile { 87 var err error 88 if v, err = expand1(chunk{f: f, b: b}, nil); err != nil { 89 return nil, err 90 } 91 } 92 m[col.name] = v 93 } 94 for i, e := range x.exprList { 95 v, err := e.eval(ctx, m) 96 if err != nil { 97 return nil, err 98 } 99 100 if ok, typ := isBlobType(v); ok { 101 return nil, fmt.Errorf("value of a complex index cannot be of blob-like type: %v", typ) 102 } 103 104 vlist[i] = v 105 } 106 return vlist, nil 107 } 108 109 type indexKey struct { 110 value []interface{} 111 h int64 112 } 113 114 // storage fields 115 // 0: next int64 116 // 1: scols string 117 // 2: hhead int64 118 // 3: name string 119 // 4: indices string - optional 120 // 5: hxroots int64 - optional 121 type table struct { 122 cols []*col // logical 123 cols0 []*col // physical 124 h int64 // 125 head int64 // head of the single linked record list 126 hhead int64 // handle of the head of the single linked record list 127 hxroots int64 128 indices []*indexedCol 129 indices2 map[string]*index2 130 name string 131 next int64 // single linked table list 132 store storage 133 tnext *table 134 tprev *table 135 xroots []interface{} 136 constraints []*constraint 137 defaults []expression 138 } 139 140 func (t *table) hasIndices() bool { return len(t.indices) != 0 || len(t.indices2) != 0 } 141 142 func (t *table) constraintsAndDefaults(ctx *execCtx) error { 143 if isSystemName[t.name] { 144 return nil 145 } 146 147 _, ok := ctx.db.root.tables["__Column2"] 148 if !ok { 149 return nil 150 } 151 152 cols := t.cols 153 constraints := make([]*constraint, len(cols)) 154 defaults := make([]expression, len(cols)) 155 arg := []interface{}{t.name} 156 rs, err := selectColumn2.l[0].exec(&execCtx{db: ctx.db, arg: arg}) 157 if err != nil { 158 return err 159 } 160 161 var rows [][]interface{} 162 ok = false 163 if err := rs.(recordset).do( 164 &execCtx{db: ctx.db, arg: arg}, 165 func(id interface{}, data []interface{}) (more bool, err error) { 166 rows = append(rows, data) 167 return true, nil 168 }, 169 ); err != nil { 170 return err 171 } 172 173 for _, row := range rows { 174 nm := row[0].(string) 175 nonNull := row[1].(bool) 176 cexpr := row[2].(string) 177 dexpr := row[3].(string) 178 for i, c := range cols { 179 if c.name == nm { 180 var co *constraint 181 if nonNull || cexpr != "" { 182 co = &constraint{} 183 constraints[i] = co 184 if cexpr != "" { 185 if co.expr, err = ctx.db.str2expr(cexpr); err != nil { 186 return fmt.Errorf("constraint %q: %v", cexpr, err) 187 } 188 } 189 190 t.constraints = constraints 191 } 192 if dexpr != "" { 193 if defaults[i], err = ctx.db.str2expr(dexpr); err != nil { 194 return fmt.Errorf("constraint %q: %v", dexpr, err) 195 } 196 197 t.defaults = defaults 198 } 199 } 200 } 201 } 202 return nil 203 } 204 205 func (t *table) checkConstraintsAndDefaults(ctx *execCtx, row []interface{}, m map[interface{}]interface{}) error { 206 cols := t.cols 207 208 if len(t.defaults) != 0 { 209 // 1. 210 for _, c := range cols { 211 m[c.name] = row[c.index] 212 } 213 214 // 2. 215 for i, c := range cols { 216 val := row[c.index] 217 expr := t.defaults[i] 218 if val != nil || expr == nil { 219 continue 220 } 221 222 dval, err := expr.eval(ctx, m) 223 if err != nil { 224 return err 225 } 226 227 row[c.index] = dval 228 if err = typeCheck(row, []*col{c}); err != nil { 229 return err 230 } 231 } 232 } 233 234 if len(t.constraints) != 0 { 235 // 3. 236 for _, c := range cols { 237 m[c.name] = row[c.index] 238 } 239 240 // 4. 241 for i, c := range cols { 242 constraint := t.constraints[i] 243 if constraint == nil { 244 continue 245 } 246 247 val := row[c.index] 248 expr := constraint.expr 249 if expr == nil { // Constraint: NOT NULL 250 if val == nil { 251 return fmt.Errorf("column %s: constraint violation: NOT NULL", c.name) 252 } 253 254 continue 255 } 256 257 // Constraint is an expression 258 cval, err := expr.eval(ctx, m) 259 if err != nil { 260 return err 261 } 262 263 if cval == nil { 264 return fmt.Errorf("column %s: constraint violation: %s", c.name, expr) 265 } 266 267 bval, ok := cval.(bool) 268 if !ok { 269 return fmt.Errorf("column %s: non bool constraint expression: %s", c.name, expr) 270 } 271 272 if !bval { 273 return fmt.Errorf("column %s: constraint violation: %s", c.name, expr) 274 } 275 } 276 } 277 278 return nil 279 } 280 281 func (t *table) clone() *table { 282 r := &table{} 283 *r = *t 284 r.constraints = append([]*constraint(nil), t.constraints...) 285 r.defaults = append([]expression(nil), t.defaults...) 286 r.indices2 = nil 287 if n := len(t.indices2); n != 0 { 288 r.indices2 = make(map[string]*index2, n) 289 for k, v := range t.indices2 { 290 r.indices2[k] = v 291 } 292 } 293 r.cols = make([]*col, len(t.cols)) 294 for i, v := range t.cols { 295 c := &col{} 296 *c = *v 297 r.cols[i] = c 298 } 299 r.cols0 = make([]*col, len(t.cols0)) 300 for i, v := range t.cols0 { 301 c := &col{} 302 *c = *v 303 r.cols0[i] = c 304 } 305 r.indices = make([]*indexedCol, len(t.indices)) 306 for i, v := range t.indices { 307 if v != nil { 308 c := &indexedCol{} 309 *c = *v 310 r.indices[i] = c 311 } 312 } 313 r.xroots = make([]interface{}, len(t.xroots)) 314 copy(r.xroots, t.xroots) 315 r.tnext, r.tprev = nil, nil 316 return r 317 } 318 319 func (t *table) findIndexByColName(name string) (*col, *indexedCol) { 320 for i, v := range t.indices { 321 if v == nil { 322 continue 323 } 324 325 if i == 0 { 326 if name == "id()" { 327 return idCol, v 328 } 329 330 continue 331 } 332 333 if c := t.cols[i-1]; c.name == name { 334 return c, v 335 } 336 } 337 338 return nil, nil 339 } 340 341 func (t *table) findIndexByName(name string) interface{} { 342 for _, v := range t.indices { 343 if v != nil && v.name == name { 344 return v 345 } 346 } 347 for k, v := range t.indices2 { 348 if k == name { 349 return v 350 } 351 } 352 return nil 353 } 354 355 func (t *table) load() (err error) { 356 data, err := t.store.Read(nil, t.h) 357 if err != nil { 358 return 359 } 360 361 var hasIndices bool 362 switch n := len(data); n { 363 case 4: 364 case 6: 365 hasIndices = true 366 default: 367 return fmt.Errorf("corrupted DB: table data len %d", n) 368 } 369 370 var ok bool 371 if t.next, ok = data[0].(int64); !ok { 372 return fmt.Errorf("corrupted DB: table data[0] of type %T", data[0]) 373 } 374 375 scols, ok := data[1].(string) 376 if !ok { 377 return fmt.Errorf("corrupted DB: table data[1] of type %T", data[1]) 378 } 379 380 if t.hhead, ok = data[2].(int64); !ok { 381 return fmt.Errorf("corrupted DB: table data[2] of type %T", data[2]) 382 } 383 384 if t.name, ok = data[3].(string); !ok { 385 return fmt.Errorf("corrupted DB: table data[3] of type %T", data[3]) 386 } 387 388 var head []interface{} 389 if head, err = t.store.Read(nil, t.hhead); err != nil { 390 return err 391 } 392 393 if len(head) != 1 { 394 return fmt.Errorf("corrupted DB: table head data len %d", len(head)) 395 } 396 397 if t.head, ok = head[0].(int64); !ok { 398 return fmt.Errorf("corrupted DB: table head data[0] of type %T", head[0]) 399 } 400 401 a := strings.Split(scols, "|") 402 t.cols0 = make([]*col, len(a)) 403 for i, v := range a { 404 if len(v) < 1 { 405 return fmt.Errorf("corrupted DB: field info %q", v) 406 } 407 408 col := &col{name: v[1:], typ: int(v[0]), index: i} 409 t.cols0[i] = col 410 if col.name != "" { 411 t.cols = append(t.cols, col) 412 } 413 } 414 415 if !hasIndices { 416 return 417 } 418 419 if t.hxroots, ok = data[5].(int64); !ok { 420 return fmt.Errorf("corrupted DB: table data[5] of type %T", data[5]) 421 } 422 423 xroots, err := t.store.Read(nil, t.hxroots) 424 if err != nil { 425 return err 426 } 427 428 if g, e := len(xroots), len(t.cols0)+1; g != e { 429 return fmt.Errorf("corrupted DB: got %d index roots, expected %d", g, e) 430 } 431 432 indices, ok := data[4].(string) 433 if !ok { 434 return fmt.Errorf("corrupted DB: table data[4] of type %T", data[4]) 435 } 436 437 a = strings.Split(indices, "|") 438 if g, e := len(a), len(t.cols0)+1; g != e { 439 return fmt.Errorf("corrupted DB: got %d index definitions, expected %d", g, e) 440 } 441 442 t.indices = make([]*indexedCol, len(a)) 443 for i, v := range a { 444 if v == "" { 445 continue 446 } 447 448 if len(v) < 2 { 449 return fmt.Errorf("corrupted DB: invalid index definition %q", v) 450 } 451 452 nm := v[1:] 453 h, ok := xroots[i].(int64) 454 if !ok { 455 return fmt.Errorf("corrupted DB: table index root of type %T", xroots[i]) 456 } 457 458 if h == 0 { 459 return fmt.Errorf("corrupted DB: missing root for index %s", nm) 460 } 461 462 unique := v[0] == 'u' 463 x, err := t.store.OpenIndex(unique, h) 464 if err != nil { 465 return err 466 } 467 468 t.indices[i] = &indexedCol{nm, unique, x, h} 469 } 470 t.xroots = xroots 471 472 return 473 } 474 475 func newTable(store storage, name string, next int64, cols []*col, tprev, tnext *table) (t *table, err error) { 476 hhead, err := store.Create(int64(0)) 477 if err != nil { 478 return 479 } 480 481 scols := cols2meta(cols) 482 h, err := store.Create(next, scols, hhead, name) 483 if err != nil { 484 return 485 } 486 487 t = &table{ 488 cols0: cols, 489 h: h, 490 hhead: hhead, 491 name: name, 492 next: next, 493 store: store, 494 tnext: tnext, 495 tprev: tprev, 496 } 497 return t.updateCols(), nil 498 } 499 500 func (t *table) blobCols() (r []*col) { 501 for _, c := range t.cols0 { 502 switch c.typ { 503 case qBlob, qBigInt, qBigRat, qTime, qDuration: 504 r = append(r, c) 505 } 506 } 507 return 508 } 509 510 func (t *table) truncate() (err error) { 511 h := t.head 512 var rec []interface{} 513 blobCols := t.blobCols() 514 for h != 0 { 515 rec, err := t.store.Read(rec, h) 516 if err != nil { 517 return err 518 } 519 nh := rec[0].(int64) 520 521 if err = t.store.Delete(h, blobCols...); err != nil { //LATER remove double read for len(blobCols) != 0 522 return err 523 } 524 525 h = nh 526 } 527 if err = t.store.Update(t.hhead, 0); err != nil { 528 return 529 } 530 531 for _, v := range t.indices { 532 if v == nil { 533 continue 534 } 535 536 if err := v.x.Clear(); err != nil { 537 return err 538 } 539 } 540 for _, ix := range t.indices2 { 541 if err := ix.x.Clear(); err != nil { 542 return err 543 } 544 } 545 t.head = 0 546 return t.updated() 547 } 548 549 func (t *table) addIndex0(unique bool, indexName string, colIndex int) (int64, btreeIndex, error) { 550 switch len(t.indices) { 551 case 0: 552 indices := make([]*indexedCol, len(t.cols0)+1) 553 h, x, err := t.store.CreateIndex(unique) 554 if err != nil { 555 return -1, nil, err 556 } 557 558 indices[colIndex+1] = &indexedCol{indexName, unique, x, h} 559 xroots := make([]interface{}, len(indices)) 560 xroots[colIndex+1] = h 561 hx, err := t.store.Create(xroots...) 562 if err != nil { 563 return -1, nil, err 564 } 565 566 t.hxroots, t.xroots, t.indices = hx, xroots, indices 567 return h, x, t.updated() 568 default: 569 ex := t.indices[colIndex+1] 570 if ex != nil && ex.name != "" { 571 colName := "id()" 572 if colIndex >= 0 { 573 colName = t.cols0[colIndex].name 574 } 575 return -1, nil, fmt.Errorf("column %s already has an index: %s", colName, ex.name) 576 } 577 578 h, x, err := t.store.CreateIndex(unique) 579 if err != nil { 580 return -1, nil, err 581 } 582 583 t.xroots[colIndex+1] = h 584 if err := t.store.Update(t.hxroots, t.xroots...); err != nil { 585 return -1, nil, err 586 } 587 588 t.indices[colIndex+1] = &indexedCol{indexName, unique, x, h} 589 return h, x, t.updated() 590 } 591 } 592 593 func (t *table) addIndex(unique bool, indexName string, colIndex int) (int64, error) { 594 hx, x, err := t.addIndex0(unique, indexName, colIndex) 595 if err != nil { 596 return -1, err 597 } 598 599 // Must fill the new index. 600 ncols := len(t.cols0) 601 h, store := t.head, t.store 602 for h != 0 { 603 rec, err := store.Read(nil, h, t.cols...) 604 if err != nil { 605 return -1, err 606 } 607 608 if n := ncols + 2 - len(rec); n > 0 { 609 rec = append(rec, make([]interface{}, n)...) 610 } 611 612 if err = x.Create([]interface{}{rec[colIndex+2]}, h); err != nil { 613 return -1, err 614 } 615 616 h = rec[0].(int64) 617 } 618 return hx, nil 619 } 620 621 func (t *table) addIndex2(execCtx *execCtx, unique bool, indexName string, exprList []expression) (int64, error) { 622 if _, ok := t.indices2[indexName]; ok { 623 panic("internal error 009") 624 } 625 626 hx, x, err := t.store.CreateIndex(unique) 627 if err != nil { 628 return -1, err 629 } 630 var a []string 631 for _, v := range exprList { 632 a = append(a, v.String()) 633 } 634 x2 := &index2{unique, x, hx, a, exprList} 635 if t.indices2 == nil { 636 t.indices2 = map[string]*index2{} 637 } 638 t.indices2[indexName] = x2 639 640 // Must fill the new index. 641 m := map[interface{}]interface{}{} 642 h, store := t.head, t.store 643 for h != 0 { 644 rec, err := store.Read(nil, h, t.cols...) 645 if err != nil { 646 return -1, err 647 } 648 649 for _, col := range t.cols { 650 ci := col.index 651 v := interface{}(nil) 652 if ci < len(rec) { 653 v = rec[ci+2] 654 } 655 m[col.name] = v 656 } 657 658 id := rec[1].(int64) 659 vlist, err := x2.eval(execCtx, t.cols, id, rec[2:]) 660 if err != nil { 661 return -1, err 662 } 663 664 if err := x2.x.Create(vlist, h); err != nil { 665 return -1, err 666 } 667 668 h = rec[0].(int64) 669 } 670 return hx, nil 671 } 672 673 func (t *table) dropIndex(xIndex int) error { 674 t.xroots[xIndex] = 0 675 if err := t.indices[xIndex].x.Drop(); err != nil { 676 return err 677 } 678 679 t.indices[xIndex] = nil 680 return t.updated() 681 } 682 683 func (t *table) updated() (err error) { 684 switch { 685 case len(t.indices) != 0: 686 a := []string{} 687 for _, v := range t.indices { 688 if v == nil { 689 a = append(a, "") 690 continue 691 } 692 693 s := "n" 694 if v.unique { 695 s = "u" 696 } 697 a = append(a, s+v.name) 698 } 699 return t.store.Update(t.h, t.next, cols2meta(t.updateCols().cols0), t.hhead, t.name, strings.Join(a, "|"), t.hxroots) 700 default: 701 return t.store.Update(t.h, t.next, cols2meta(t.updateCols().cols0), t.hhead, t.name) 702 } 703 } 704 705 // storage fields 706 // 0: next record handle int64 707 // 1: record id int64 708 // 2...: data row 709 func (t *table) addRecord(execCtx *execCtx, r []interface{}) (id int64, err error) { 710 if id, err = t.store.ID(); err != nil { 711 return 712 } 713 714 r = append([]interface{}{t.head, id}, r...) 715 h, err := t.store.Create(r...) 716 if err != nil { 717 return 718 } 719 720 for i, v := range t.indices { 721 if v == nil { 722 continue 723 } 724 725 if err = v.x.Create([]interface{}{r[i+1]}, h); err != nil { 726 return 727 } 728 } 729 730 for _, ix := range t.indices2 { 731 vlist, err := ix.eval(execCtx, t.cols, id, r[2:]) 732 if err != nil { 733 return -1, err 734 } 735 736 if err := ix.x.Create(vlist, h); err != nil { 737 return -1, err 738 } 739 } 740 741 if err = t.store.Update(t.hhead, h); err != nil { 742 return 743 } 744 745 t.head = h 746 return 747 } 748 749 func (t *table) fieldNames() []string { 750 r := make([]string, len(t.cols)) 751 for i, v := range t.cols { 752 r[i] = v.name 753 } 754 return r 755 } 756 757 func (t *table) updateCols() *table { 758 t.cols = t.cols[:0] 759 for i, c := range t.cols0 { 760 if c.name != "" { 761 c.index = i 762 t.cols = append(t.cols, c) 763 } 764 } 765 return t 766 } 767 768 func (t *table) row0(ctx *execCtx, h int64) ([]interface{}, error) { 769 rec, err := ctx.db.store.Read(nil, h, t.cols...) 770 if err != nil { 771 return nil, err 772 } 773 774 if d := len(t.cols) - (len(rec) - 2); d > 0 { 775 rec = append(rec, make([]interface{}, d)...) 776 } 777 778 return rec, nil 779 } 780 781 func (t *table) row(ctx *execCtx, h int64) (int64, []interface{}, error) { 782 rec, err := t.row0(ctx, h) 783 if err != nil { 784 return -1, nil, err 785 } 786 787 return rec[1].(int64), rec[2:], nil 788 } 789 790 // storage fields 791 // 0: handle of first table in DB int64 792 type root struct { 793 head int64 // Single linked table list 794 lastInsertID int64 795 parent *root 796 //rowsAffected int64 //LATER implement 797 store storage 798 tables map[string]*table 799 thead *table 800 } 801 802 func newRoot(store storage) (r *root, err error) { 803 data, err := store.Read(nil, 1) 804 if err != nil { 805 return 806 } 807 808 switch len(data) { 809 case 0: // new empty DB, create empty table list 810 if err = store.BeginTransaction(); err != nil { 811 return 812 } 813 814 if err = store.Update(1, int64(0)); err != nil { 815 store.Rollback() 816 return 817 } 818 819 if err = store.Commit(); err != nil { 820 return 821 } 822 823 return &root{ 824 store: store, 825 tables: map[string]*table{}, 826 }, nil 827 case 1: // existing DB, load tables 828 if len(data) != 1 { 829 return nil, fmt.Errorf("corrupted DB: root is an %d-scalar", len(data)) 830 } 831 832 p, ok := data[0].(int64) 833 if !ok { 834 return nil, fmt.Errorf("corrupted DB: root head has type %T", data[0]) 835 } 836 837 r := &root{ 838 head: p, 839 store: store, 840 tables: map[string]*table{}, 841 } 842 843 var tprev *table 844 for p != 0 { 845 t := &table{ 846 h: p, 847 store: store, 848 tprev: tprev, 849 } 850 851 if r.thead == nil { 852 r.thead = t 853 } 854 if tprev != nil { 855 tprev.tnext = t 856 } 857 tprev = t 858 859 if err = t.load(); err != nil { 860 return nil, err 861 } 862 863 if r.tables[t.name] != nil { // duplicate 864 return nil, fmt.Errorf("corrupted DB: duplicate table metadata for table %s", t.name) 865 } 866 867 r.tables[t.name] = t 868 p = t.next 869 } 870 return r, nil 871 default: 872 return nil, errIncompatibleDBFormat 873 } 874 } 875 876 func (r *root) findIndexByName(name string) (*table, interface{}) { 877 for _, t := range r.tables { 878 if i := t.findIndexByName(name); i != nil { 879 return t, i 880 } 881 } 882 883 return nil, nil 884 } 885 886 func (r *root) updated() (err error) { 887 return r.store.Update(1, r.head) 888 } 889 890 func (r *root) createTable(name string, cols []*col) (t *table, err error) { 891 if _, ok := r.tables[name]; ok { 892 panic("internal error 065") 893 } 894 895 if t, err = newTable(r.store, name, r.head, cols, nil, r.thead); err != nil { 896 return nil, err 897 } 898 899 if err = r.store.Update(1, t.h); err != nil { 900 return nil, err 901 } 902 903 if p := r.thead; p != nil { 904 p.tprev = t 905 } 906 r.tables[name], r.head, r.thead = t, t.h, t 907 return 908 } 909 910 func (r *root) dropTable(t *table) (err error) { 911 defer func() { 912 if err != nil { 913 return 914 } 915 916 delete(r.tables, t.name) 917 }() 918 919 if err = t.truncate(); err != nil { 920 return 921 } 922 923 if err = t.store.Delete(t.hhead); err != nil { 924 return 925 } 926 927 if err = t.store.Delete(t.h); err != nil { 928 return 929 } 930 931 for _, v := range t.indices { 932 if v != nil && v.x != nil { 933 if err = v.x.Drop(); err != nil { 934 return 935 } 936 } 937 } 938 for _, v := range t.indices2 { 939 if err = v.x.Drop(); err != nil { 940 return 941 } 942 } 943 944 if h := t.hxroots; h != 0 { 945 if err = t.store.Delete(h); err != nil { 946 return 947 } 948 } 949 950 switch { 951 case t.tprev == nil && t.tnext == nil: 952 r.head = 0 953 r.thead = nil 954 err = r.updated() 955 return errSet(&err, r.store.ResetID()) 956 case t.tprev == nil && t.tnext != nil: 957 next := t.tnext 958 next.tprev = nil 959 r.head = next.h 960 r.thead = next 961 if err = r.updated(); err != nil { 962 return 963 } 964 965 return next.updated() 966 case t.tprev != nil && t.tnext == nil: // last in list 967 prev := t.tprev 968 prev.next = 0 969 prev.tnext = nil 970 return prev.updated() 971 default: //case t.tprev != nil && t.tnext != nil: 972 prev, next := t.tprev, t.tnext 973 prev.next = next.h 974 prev.tnext = next 975 next.tprev = prev 976 if err = prev.updated(); err != nil { 977 return 978 } 979 980 return next.updated() 981 } 982 }