Commit 1fb615dc authored by Kirill Smelkov's avatar Kirill Smelkov

X draft of catobj

parent 8cb4e9c0
...@@ -88,7 +88,7 @@ func openClientByURL(u *url.URL) (zodb.IStorage, error) { ...@@ -88,7 +88,7 @@ func openClientByURL(u *url.URL) (zodb.IStorage, error) {
return nil, err return nil, err
} }
// identify ourselves via conn // first identify ourselves via conn
storType, err := IdentifyMe(storLink, CLIENT) storType, err := IdentifyMe(storLink, CLIENT)
if err != nil { if err != nil {
return nil, err // XXX err ctx return nil, err // XXX err ctx
...@@ -98,6 +98,7 @@ func openClientByURL(u *url.URL) (zodb.IStorage, error) { ...@@ -98,6 +98,7 @@ func openClientByURL(u *url.URL) (zodb.IStorage, error) {
return nil, fmt.Errorf("%v: peer is not storage (identifies as %v)", storLink, storType) return nil, fmt.Errorf("%v: peer is not storage (identifies as %v)", storLink, storType)
} }
// identification passed
conn, err := storLink.NewConn() conn, err := storLink.NewConn()
if err != nil { if err != nil {
return nil, err // XXX err ctx ? return nil, err // XXX err ctx ?
......
...@@ -29,13 +29,13 @@ type Tid uint64 // transaction identifier ...@@ -29,13 +29,13 @@ type Tid uint64 // transaction identifier
type Oid uint64 // object identifier type Oid uint64 // object identifier
// XTid is "extended" transaction identifier. It defines a transaction for // XTid is "extended" transaction identifier. It defines a transaction for
// oid lookup - either exactly by serial, or <beforeTid XXX // oid lookup - either exactly by serial, or by < beforeTid.
type XTid struct { type XTid struct {
Tid Tid
TidBefore bool // XXX merge into Tid itself (high bit) ? TidBefore bool // XXX merge into Tid itself (high bit) ?
} }
// Xid is "extended" oid = oid + serial/beforeTid, completely specifying object revision XXX text // Xid is "extended" oid = oid + serial/beforeTid, completely specifying object address.
type Xid struct { type Xid struct {
XTid XTid
Oid Oid
...@@ -140,7 +140,7 @@ type IStorage interface { ...@@ -140,7 +140,7 @@ type IStorage interface {
// LoadSerial and LoadBefore generalized into 1 Load (see Xid for details) // LoadSerial and LoadBefore generalized into 1 Load (see Xid for details)
// TODO data []byte -> something allocated from slab ? // TODO data []byte -> something allocated from slab ?
Load(xid Xid) (data []byte, tid Tid, err error) Load(xid Xid) (data []byte, tid Tid, err error) // XXX -> StorageRecordInformation ?
// -> Prefetch(xid Xid) ... // -> Prefetch(xid Xid) ...
// PrefetchBefore(oidv []Oid, beforeTid Tid) error (?) // PrefetchBefore(oidv []Oid, beforeTid Tid) error (?)
......
// Copyright (C) 2017 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
//
// This program is free software: you can Use, Study, Modify and Redistribute
// it under the terms of the GNU General Public License version 3, or (at your
// option) any later version, as published by the Free Software Foundation.
//
// You can also Link and Combine this program with other software covered by
// the terms of any of the Open Source Initiative approved licenses and Convey
// the resulting work. Corresponding source of such a combination shall include
// the source code for all other software used.
//
// This program is distributed WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
// See COPYING file for full licensing terms.
package zodbtools
// Catobj - dump content of a database object
import (
"flag"
"fmt"
"io"
"log"
"os"
"../../zodb"
)
// Catobj dumps content of one ZODB object XXX text
func Catobj(w io.Writer, stor zodb.IStorage, xid zodb.Xid) error {
var objInfo zodb.StorageRecordInformation
data, tid, err := stor.Load(xid)
if err != nil {
return err
}
// XXX hack - rework IStorage.Load to fill-in objInfo directly
objInfo.Oid = xid.Oid
objInfo.Tid = tid
objInfo.Data = data
objInfo.DataTid = tid // XXX wrong
d := dumper{W: w} // XXX HashOnly + raw dump
err = d.DumpData(&objInfo)
return err
}
// ----------------------------------------
const catobjSummary = "dump content of a database object"
func catobjUsage(w io.Writer) {
fmt.Fprintf(w,
`Usage: zodb catobj [OPTIONS] <storage> xid...
Dump content of a ZODB database object.
<storage> is an URL (see 'zodb help zurl') of a ZODB-storage.
xid is object address (see 'zodb help xid').
Options:
-h --help this help text.
// -hashonly dump only hashes of objects without content. XXX
`)
}
func catobjMain(argv []string) {
flags := flag.FlagSet{Usage: func() { dumpUsage(os.Stderr) }}
flags.Init("", flag.ExitOnError)
// flags.BoolVar(&hashOnly, "hashonly", hashOnly, "dump only hashes of objects")
flags.Parse(argv[1:])
argv = flags.Args()
if len(argv) < 2 {
flags.Usage()
os.Exit(2)
}
storUrl := argv[0]
xidv := []zodb.Xid{}
for _, arg := range argv[1:] {
xid, err := zodb.ParseXid(arg)
if err != nil {
log.Fatal(err) // XXX recheck
}
xidv = append(xidv, xid)
}
stor, err := zodb.OpenStorageURL(storUrl) // TODO read-only
if err != nil {
log.Fatal(err)
}
// TODO defer stor.Close()
for _, xid := range xidv {
err = Catobj(os.Stdout, stor, xid)
if err != nil {
log.Fatal(err)
}
}
}
...@@ -46,6 +46,7 @@ var Commands = CommandRegistry{ ...@@ -46,6 +46,7 @@ var Commands = CommandRegistry{
// NOTE the order commands are listed here is the order how they will appear in help // NOTE the order commands are listed here is the order how they will appear in help
// TODO analyze ? // TODO analyze ?
// TODO cmp // TODO cmp
{"dump", dumpSummary, dumpUsage, dumpMain},
{"info", infoSummary, infoUsage, infoMain}, {"info", infoSummary, infoUsage, infoMain},
{"dump", dumpSummary, dumpUsage, dumpMain},
{"catobj", catobjSummary, catobjUsage, catobjMain},
} }
...@@ -64,6 +64,7 @@ var _LF = []byte{'\n'} ...@@ -64,6 +64,7 @@ var _LF = []byte{'\n'}
// DumpData dumps one data record // DumpData dumps one data record
// XXX naming -> DumpObj ?
func (d *dumper) DumpData(datai *zodb.StorageRecordInformation) error { func (d *dumper) DumpData(datai *zodb.StorageRecordInformation) error {
buf := &d.buf buf := &d.buf
buf.Reset() buf.Reset()
...@@ -235,7 +236,6 @@ func dumpMain(argv []string) { ...@@ -235,7 +236,6 @@ func dumpMain(argv []string) {
} }
storUrl := argv[0] storUrl := argv[0]
if len(argv) > 1 { if len(argv) > 1 {
tidRange = argv[1] tidRange = argv[1]
} }
......
...@@ -69,3 +69,8 @@ http://docs.pylonsproject.org/projects/zodburi/ ...@@ -69,3 +69,8 @@ http://docs.pylonsproject.org/projects/zodburi/
var HelpTopics = HelpRegistry{ var HelpTopics = HelpRegistry{
{"zurl", "specifying database URL", helpZURL}, {"zurl", "specifying database URL", helpZURL},
} }
// TODO xid
// TODO dump format
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment