zodb.go 4.14 KB
Newer Older
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
1 2
// TODO copyright / license

Kirill Smelkov's avatar
.  
Kirill Smelkov committed
3
// Package zodb defines types, interfaces and errors used in ZODB databases
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
4

Kirill Smelkov's avatar
.  
Kirill Smelkov committed
5 6
// XXX partly based on ZODB/py

Kirill Smelkov's avatar
.  
Kirill Smelkov committed
7 8
package zodb

Kirill Smelkov's avatar
.  
Kirill Smelkov committed
9 10 11 12
import (
	"fmt"
)

Kirill Smelkov's avatar
.  
Kirill Smelkov committed
13 14 15 16
// ZODB types
type Tid uint64  // transaction identifier
type Oid uint64  // object identifier

Kirill Smelkov's avatar
.  
Kirill Smelkov committed
17 18 19
// XTid is "extended" transaction identifier. It defines a transaction for
// oid lookup - either exactly by serial, or <beforeTid	XXX
type XTid struct {
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
20
	Tid
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
21 22 23
	TidBefore bool	// XXX merge into Tid itself (high bit) ?
}

Kirill Smelkov's avatar
.  
Kirill Smelkov committed
24
// Xid is "extended" oid = oid + serial/beforeTid, completely specifying object revision	XXX text
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
25 26
type Xid struct {
	XTid
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
27
	Oid
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
28 29
}

Kirill Smelkov's avatar
.  
Kirill Smelkov committed
30
const (
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
31
	//Tid0	Tid = 0			// XXX -> simply Tid(0) ?
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
32 33 34
	TidMax	Tid = 1<<63 - 1		// 0x7fffffffffffffff
					// ZODB defines maxtid to be max signed int64 since baee84a6 (Jun 7 2016)
					// (XXX in neo: SQLite does not accept numbers above 2^63-1)
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
35

Kirill Smelkov's avatar
.  
Kirill Smelkov committed
36
	//Oid0	Oid = 0			// XXX -> simply Oid(0)
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
37 38
)

Kirill Smelkov's avatar
.  
Kirill Smelkov committed
39 40 41 42 43 44 45 46 47
func (tid Tid) Valid() bool {
	// XXX if Tid becomes signed also check wrt 0
	if tid <= TidMax {
		return true
	} else {
		return false
	}
}

Kirill Smelkov's avatar
.  
Kirill Smelkov committed
48 49
// ----------------------------------------

Kirill Smelkov's avatar
.  
Kirill Smelkov committed
50
// ErrOidMissing is an error which tells that there is no such oid in the database at all
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
51 52 53 54 55
type ErrOidMissing struct {
	Oid	Oid
}

func (e ErrOidMissing) Error() string {
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
56
	return fmt.Sprintf("%v: no such oid", e.Oid)
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
57 58
}

Kirill Smelkov's avatar
.  
Kirill Smelkov committed
59 60 61 62 63
// ErrXidMissing is an error which tells that oid exists in the database,
// but there is no its revision satisfying xid.XTid search criteria.
type ErrXidMissing struct {
	Xid	Xid
}
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
64

Kirill Smelkov's avatar
.  
Kirill Smelkov committed
65
func (e *ErrXidMissing) Error() string {
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
66
	return fmt.Sprintf("%v: no matching data record found", e.Xid)
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
67 68
}

Kirill Smelkov's avatar
.  
Kirill Smelkov committed
69 70
// ----------------------------------------

Kirill Smelkov's avatar
.  
Kirill Smelkov committed
71
// TxnStatus represents status of a transaction
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
72 73
type TxnStatus byte

Kirill Smelkov's avatar
.  
Kirill Smelkov committed
74 75 76 77 78 79
const (
	TxnComplete TxnStatus = ' ' // completed transaction that hasn't been packed
	TxnPacked             = 'p' // completed transaction that has been packed
	TxnInprogress         = 'c' // checkpoint -- a transaction in progress; it's been thru vote() but not finish()
)

Kirill Smelkov's avatar
.  
Kirill Smelkov committed
80 81 82 83 84 85 86 87 88 89 90
// Valid returns true if transaction status value is well-known and valid
func (ts TxnStatus) Valid() bool {
	switch ts {
	case TxnComplete, TxnPacked, TxnInprogress:
		return true

	default:
		return false
	}
}

Kirill Smelkov's avatar
.  
Kirill Smelkov committed
91
// Metadata information about single transaction
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
92
type TxnInfo struct {
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
93 94 95 96 97
	Tid         Tid
	Status      TxnStatus
	User        []byte
	Description []byte
	Extension   []byte
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
98 99 100
}

// Information about single storage record
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
101
// XXX naming
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
102
type StorageRecordInformation struct {
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
103 104 105 106 107 108 109
	Oid	Oid
	Tid	Tid
	Data	[]byte	// nil means: deleted

	// original tid data was committed (e.g. in case of undo)
	// XXX we don't really need this
	DataTid	Tid
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
110 111 112 113 114
}



type IStorage interface {
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
115
	Close() error
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
116

Kirill Smelkov's avatar
.  
Kirill Smelkov committed
117 118
	// StorageName returns storage name
	StorageName() string
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
119

Kirill Smelkov's avatar
.  
Kirill Smelkov committed
120
	// History(oid, size=1)
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
121

Kirill Smelkov's avatar
.  
Kirill Smelkov committed
122 123 124 125
	// LastTid returns the id of the last committed transaction.
	// if not transactions have been committed yet, LastTid returns Tid zero value
	// XXX ^^^ ok ?
	LastTid() Tid	// XXX -> Tid, ok ?
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
126

Kirill Smelkov's avatar
.  
Kirill Smelkov committed
127
	// LoadSerial and LoadBefore generalized into 1 Load  (see Xid for details)
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
128
	// TODO data []byte -> something allocated from slab ?
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
129
	Load(xid Xid) (data []byte, tid Tid, err error)
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
130

Kirill Smelkov's avatar
.  
Kirill Smelkov committed
131
	// -> Prefetch(xid Xid) ...
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
132
	// PrefetchBefore(oidv []Oid, beforeTid Tid) error (?)
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
133

Kirill Smelkov's avatar
.  
Kirill Smelkov committed
134 135 136
	// Store(oid Oid, serial Tid, data []byte, txn ITransaction) error
	// XXX Restore ?
	// CheckCurrentSerialInTransaction(oid Oid, serial Tid, txn ITransaction)   // XXX naming
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
137

Kirill Smelkov's avatar
.  
Kirill Smelkov committed
138 139 140 141
	// tpc_begin(txn)
	// tpc_vote(txn)
	// tpc_finish(txn, callback)    XXX clarify about callback
	// tpc_abort(txn)
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
142

Kirill Smelkov's avatar
.  
Kirill Smelkov committed
143
	Iterate(tidMin, tidMax Tid) IStorageIterator	// XXX , error ?
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
144 145 146
}

type IStorageIterator interface {
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
147 148 149
	// NextTxn yields information about next database transaction:
	// 1. transaction metadata, and
	// 2. iterator over transaction data records. 
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
150
	// transaction metadata stays valid until next call to NextTxn().
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
151
	// end of iteration is indicated with io.EOF
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
152
	NextTxn() (*TxnInfo, IStorageRecordIterator, error)
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
153 154 155
}

type IStorageRecordIterator interface {         // XXX naming -> IRecordIterator
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
156 157
	// NextData yields information about next storage data record.
	// returned data stays valid until next call to NextData().
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
158
	// end of iteration is indicated with io.EOF
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
159
	NextData() (*StorageRecordInformation, error)
Kirill Smelkov's avatar
.  
Kirill Smelkov committed
160
}