mirror of
https://github.com/mumble-voip/grumble.git
synced 2026-01-24 04:19:42 -08:00
Major gofix run.
This commit is contained in:
parent
92e6ac5276
commit
71b8314c2e
28 changed files with 522 additions and 559 deletions
|
|
@ -8,9 +8,9 @@ import (
|
|||
"bytes"
|
||||
"crypto/sha1"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"hash"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
// blobReader is based on the principles of the checksumReader from the archive/zip
|
||||
|
|
@ -18,7 +18,7 @@ import (
|
|||
|
||||
// ErrHashMismatch is returned if a blobReader has read a file whose computed hash
|
||||
// did not match its key.
|
||||
var ErrHashMismatch = os.NewError("hash mismatch")
|
||||
var ErrHashMismatch = errors.New("hash mismatch")
|
||||
|
||||
// blobReader reads a blob from disk, hashing all incoming data. On EOF, it checks
|
||||
// whether the read data matches the key.
|
||||
|
|
@ -28,7 +28,7 @@ type blobReader struct {
|
|||
hash hash.Hash
|
||||
}
|
||||
|
||||
func newBlobReader(rc io.ReadCloser, key string) (br *blobReader, err os.Error) {
|
||||
func newBlobReader(rc io.ReadCloser, key string) (br *blobReader, err error) {
|
||||
sum, err := hex.DecodeString(key)
|
||||
if err != nil {
|
||||
return
|
||||
|
|
@ -36,10 +36,10 @@ func newBlobReader(rc io.ReadCloser, key string) (br *blobReader, err os.Error)
|
|||
return &blobReader{rc, sum, sha1.New()}, nil
|
||||
}
|
||||
|
||||
func (r *blobReader) Read(b []byte) (n int, err os.Error) {
|
||||
func (r *blobReader) Read(b []byte) (n int, err error) {
|
||||
n, err = r.rc.Read(b)
|
||||
r.hash.Write(b[:n])
|
||||
if err != os.EOF {
|
||||
if err != io.EOF {
|
||||
return
|
||||
}
|
||||
if !bytes.Equal(r.sum, r.hash.Sum()) {
|
||||
|
|
@ -48,6 +48,6 @@ func (r *blobReader) Read(b []byte) (n int, err os.Error) {
|
|||
return
|
||||
}
|
||||
|
||||
func (r *blobReader) Close() os.Error {
|
||||
func (r *blobReader) Close() error {
|
||||
return r.rc.Close()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ package blobstore
|
|||
import (
|
||||
"crypto/sha1"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
|
@ -26,11 +27,11 @@ const (
|
|||
)
|
||||
|
||||
var (
|
||||
ErrLocked = os.NewError("lockfile acquired by another process")
|
||||
ErrLockAcquirement = os.NewError("unable to acquire lockfile")
|
||||
ErrBadFile = os.NewError("a bad file exists in the blobstore directory. unable to create container directores.")
|
||||
ErrNoSuchKey = os.NewError("no such key")
|
||||
ErrInvalidKey = os.NewError("invalid key")
|
||||
ErrLocked = errors.New("lockfile acquired by another process")
|
||||
ErrLockAcquirement = errors.New("unable to acquire lockfile")
|
||||
ErrBadFile = errors.New("a bad file exists in the blobstore directory. unable to create container directores.")
|
||||
ErrNoSuchKey = errors.New("no such key")
|
||||
ErrInvalidKey = errors.New("invalid key")
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -41,7 +42,7 @@ var (
|
|||
// Open an existing, or create a new BlobStore at path.
|
||||
// Path must point to a directory, and must already exist.
|
||||
// See NewBlobStore for more information.
|
||||
func Open(path string, makeall bool) (err os.Error) {
|
||||
func Open(path string, makeall bool) (err error) {
|
||||
defaultMutex.Lock()
|
||||
defer defaultMutex.Unlock()
|
||||
|
||||
|
|
@ -55,7 +56,7 @@ func Open(path string, makeall bool) (err os.Error) {
|
|||
|
||||
// Close the open default BlobStore. This removes the lockfile allowing
|
||||
// other processes to open the BlobStore.
|
||||
func Close() (err os.Error) {
|
||||
func Close() (err error) {
|
||||
if defaultStore == nil {
|
||||
panic("DefaultStore not open")
|
||||
}
|
||||
|
|
@ -71,17 +72,16 @@ func Close() (err os.Error) {
|
|||
|
||||
// Lookup a blob by its key and return a buffer containing the contents
|
||||
// of the blob.
|
||||
func Get(key string) (buf []byte, err os.Error) {
|
||||
func Get(key string) (buf []byte, err error) {
|
||||
return defaultStore.Get(key)
|
||||
}
|
||||
|
||||
// Store a blob. If the blob was successfully stored, the returned key
|
||||
// can be used to retrieve the buf from the BlobStore.
|
||||
func Put(buf []byte) (key string, err os.Error) {
|
||||
func Put(buf []byte) (key string, err error) {
|
||||
return defaultStore.Put(buf)
|
||||
}
|
||||
|
||||
|
||||
// Open an existing, or create a new BlobStore residing at path.
|
||||
// Path must point to a directory, and must already exist.
|
||||
//
|
||||
|
|
@ -92,7 +92,7 @@ func Put(buf []byte) (key string, err os.Error) {
|
|||
// some I/O operations when writing blobs. (Since the BlobStore
|
||||
// knows that all directories will exist, it does not need to check
|
||||
// whether they do, and create them if they do not.).
|
||||
func NewBlobStore(path string, makeall bool) (bs *BlobStore, err os.Error) {
|
||||
func NewBlobStore(path string, makeall bool) (bs *BlobStore, err error) {
|
||||
// Does the directory exist?
|
||||
dir, err := os.Open(path)
|
||||
if err != nil {
|
||||
|
|
@ -130,7 +130,7 @@ func NewBlobStore(path string, makeall bool) (bs *BlobStore, err os.Error) {
|
|||
if !fi.IsDirectory() {
|
||||
return nil, ErrBadFile
|
||||
}
|
||||
} else if e.Error == os.ENOTDIR {
|
||||
} else if e.Err == os.ENOTDIR {
|
||||
return nil, ErrBadFile
|
||||
}
|
||||
} else if err != nil {
|
||||
|
|
@ -150,7 +150,7 @@ func NewBlobStore(path string, makeall bool) (bs *BlobStore, err os.Error) {
|
|||
if !fi.IsDirectory() {
|
||||
return nil, ErrBadFile
|
||||
}
|
||||
} else if e.Error == os.ENOTDIR {
|
||||
} else if e.Err == os.ENOTDIR {
|
||||
return nil, ErrBadFile
|
||||
}
|
||||
} else if err != nil {
|
||||
|
|
@ -170,14 +170,14 @@ func NewBlobStore(path string, makeall bool) (bs *BlobStore, err os.Error) {
|
|||
|
||||
// Close an open BlobStore. This removes the lockfile allowing
|
||||
// other processes to open the BlobStore.
|
||||
func (bs *BlobStore) Close() (err os.Error) {
|
||||
func (bs *BlobStore) Close() (err error) {
|
||||
return os.Remove(bs.lockfn)
|
||||
}
|
||||
|
||||
// Checks that a given key is a valid key for the BlobStore.
|
||||
// If it is, it returns the three components that make up the on-disk path
|
||||
// the given key can be found or should be stored at.
|
||||
func getKeyComponents(key string) (dir1, dir2, fn string, err os.Error) {
|
||||
func getKeyComponents(key string) (dir1, dir2, fn string, err error) {
|
||||
// SHA1 digests are 40 bytes long when hex-encoded
|
||||
if len(key) != 40 {
|
||||
err = ErrInvalidKey
|
||||
|
|
@ -195,7 +195,7 @@ func getKeyComponents(key string) (dir1, dir2, fn string, err os.Error) {
|
|||
|
||||
// Lookup the path hat a key would have on disk.
|
||||
// Returns an error if the key is not a valid BlobStore key.
|
||||
func (bs *BlobStore) pathForKey(key string) (fn string, err os.Error) {
|
||||
func (bs *BlobStore) pathForKey(key string) (fn string, err error) {
|
||||
dir1, dir2, rest, err := getKeyComponents(key)
|
||||
if err != nil {
|
||||
return
|
||||
|
|
@ -207,14 +207,14 @@ func (bs *BlobStore) pathForKey(key string) (fn string, err os.Error) {
|
|||
|
||||
// Lookup a blob by its key and return a buffer containing the contents
|
||||
// of the blob.
|
||||
func (bs *BlobStore) Get(key string) (buf []byte, err os.Error) {
|
||||
func (bs *BlobStore) Get(key string) (buf []byte, err error) {
|
||||
fn, err := bs.pathForKey(key)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
file, err := os.Open(fn)
|
||||
if e, ok := err.(*os.PathError); ok && (e.Error == os.ENOENT || e.Error == os.ENOTDIR) {
|
||||
if e, ok := err.(*os.PathError); ok && (e.Err == os.ENOENT || e.Err == os.ENOTDIR) {
|
||||
err = ErrNoSuchKey
|
||||
return
|
||||
} else if err != nil {
|
||||
|
|
@ -238,7 +238,7 @@ func (bs *BlobStore) Get(key string) (buf []byte, err os.Error) {
|
|||
|
||||
// Store a blob. If the blob was successfully stored, the returned key
|
||||
// can be used to retrieve the buf from the BlobStore.
|
||||
func (bs *BlobStore) Put(buf []byte) (key string, err os.Error) {
|
||||
func (bs *BlobStore) Put(buf []byte) (key string, err error) {
|
||||
// Calculate the key for the blob. We can't really delay it more than this,
|
||||
// since we need to know the key for the blob to check whether it's already on
|
||||
// disk.
|
||||
|
|
@ -263,7 +263,7 @@ func (bs *BlobStore) Put(buf []byte) (key string, err os.Error) {
|
|||
file.Close()
|
||||
return
|
||||
} else {
|
||||
if e, ok := err.(*os.PathError); ok && (e.Error == os.ENOENT || e.Error == os.ENOTDIR) {
|
||||
if e, ok := err.(*os.PathError); ok && (e.Err == os.ENOENT || e.Err == os.ENOTDIR) {
|
||||
// No such file exists on disk. Ready to rock!
|
||||
} else {
|
||||
return
|
||||
|
|
@ -315,10 +315,10 @@ func (bs *BlobStore) Put(buf []byte) (key string, err os.Error) {
|
|||
// On Unix, it checks for EEXIST. On Windows, it checks for EEXIST
|
||||
// and Errno code 183 (ERROR_ALREADY_EXISTS)
|
||||
func isExistError(err *os.PathError) (exists bool) {
|
||||
if e, ok := err.Error.(os.Errno); ok && e == win32AlreadyExists {
|
||||
if e, ok := err.Err.(os.Errno); ok && e == win32AlreadyExists {
|
||||
exists = true
|
||||
}
|
||||
if err.Error == os.EEXIST {
|
||||
if err.Err == os.EEXIST {
|
||||
exists = true
|
||||
}
|
||||
return
|
||||
|
|
|
|||
|
|
@ -17,14 +17,14 @@ import (
|
|||
func TestMakeAllCreateAll(t *testing.T) {
|
||||
dir, err := ioutil.TempDir("", "blobstore")
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
bs, err := NewBlobStore(dir, true)
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
defer bs.Close()
|
||||
|
|
@ -35,7 +35,7 @@ func TestMakeAllCreateAll(t *testing.T) {
|
|||
dirname := filepath.Join(dir, hex.EncodeToString([]byte{byte(i)}), hex.EncodeToString([]byte{byte(j)}))
|
||||
fi, err := os.Stat(dirname)
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
}
|
||||
if !fi.IsDirectory() {
|
||||
t.Errorf("Not a directory")
|
||||
|
|
@ -47,65 +47,65 @@ func TestMakeAllCreateAll(t *testing.T) {
|
|||
func TestAllInvalidFiles(t *testing.T) {
|
||||
dir, err := ioutil.TempDir("", "blobstore")
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
err = ioutil.WriteFile(filepath.Join(dir, "00"), []byte{0x0f, 0x00}, 0600)
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
_, err = NewBlobStore(dir, true)
|
||||
if err == ErrBadFile {
|
||||
// Success
|
||||
} else if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
} else {
|
||||
t.Errorf("NewBlobStore returned without error")
|
||||
t.Error("NewBlobStore returned without error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAllInvalidFilesLevel2(t *testing.T) {
|
||||
dir, err := ioutil.TempDir("", "blobstore")
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
err = os.Mkdir(filepath.Join(dir, "00"), 0700)
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
err = ioutil.WriteFile(filepath.Join(dir, "00", "00"), []byte{0x0f, 0x00}, 0600)
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
_, err = NewBlobStore(dir, true)
|
||||
if err == ErrBadFile {
|
||||
// Success
|
||||
} else if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
} else {
|
||||
t.Errorf("NewBlobStore returned without error")
|
||||
t.Error("NewBlobStore returned without error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStoreRetrieve(t *testing.T) {
|
||||
dir, err := ioutil.TempDir("", "blobstore")
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
bs, err := NewBlobStore(dir, false)
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
defer bs.Close()
|
||||
|
|
@ -114,13 +114,13 @@ func TestStoreRetrieve(t *testing.T) {
|
|||
|
||||
key, err := bs.Put(data)
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
recv, err := bs.Get(key)
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if !bytes.Equal(recv, data) {
|
||||
|
|
@ -131,14 +131,14 @@ func TestStoreRetrieve(t *testing.T) {
|
|||
func TestReadNonExistantKey(t *testing.T) {
|
||||
dir, err := ioutil.TempDir("", "blobstore")
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
bs, err := NewBlobStore(dir, false)
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
defer bs.Close()
|
||||
|
|
@ -148,7 +148,7 @@ func TestReadNonExistantKey(t *testing.T) {
|
|||
key := hex.EncodeToString(h.Sum())
|
||||
buf, err := bs.Get(key)
|
||||
if err != ErrNoSuchKey {
|
||||
t.Errorf("Expected no such key %v, found it anyway. (buf=%v, err=%v)", key, buf, err)
|
||||
t.Error("Expected no such key %v, found it anyway. (buf=%v, err=%v)", key, buf, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
@ -156,13 +156,13 @@ func TestReadNonExistantKey(t *testing.T) {
|
|||
func TestReadInvalidKeyLength(t *testing.T) {
|
||||
dir, err := ioutil.TempDir("", "blobstore")
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
bs, err := NewBlobStore(dir, false)
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
defer bs.Close()
|
||||
|
|
@ -174,7 +174,7 @@ func TestReadInvalidKeyLength(t *testing.T) {
|
|||
|
||||
_, err = bs.Get(key)
|
||||
if err != ErrInvalidKey {
|
||||
t.Errorf("Expected invalid key for %v, got %v", key, err)
|
||||
t.Error("Expected invalid key for %v, got %v", key, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
@ -182,14 +182,14 @@ func TestReadInvalidKeyLength(t *testing.T) {
|
|||
func TestReadInvalidKeyNonHex(t *testing.T) {
|
||||
dir, err := ioutil.TempDir("", "blobstore")
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
bs, err := NewBlobStore(dir, false)
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
defer bs.Close()
|
||||
|
|
@ -209,26 +209,26 @@ func TestReadInvalidKeyNonHex(t *testing.T) {
|
|||
func TestDefaultBlobStore(t *testing.T) {
|
||||
dir, err := ioutil.TempDir("", "blobstore")
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
err = Open(dir, false)
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
data := []byte{0xf, 0x0, 0x0, 0xb, 0xa, 0xf}
|
||||
|
||||
key, err := Put(data)
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
fetchedData, err := Get(key)
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if !bytes.Equal(fetchedData, data) {
|
||||
|
|
|
|||
|
|
@ -1,73 +1,73 @@
|
|||
// Copyright (c) 2011 The Grumble Authors
|
||||
// The use of this source code is goverened by a BSD-style
|
||||
// license that can be found in the LICENSE-file.
|
||||
|
||||
package blobstore
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"io/ioutil"
|
||||
"strconv"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
|
||||
package blobstore
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// Acquire lockfile at path.
|
||||
func AcquireLockFile(path string) os.Error {
|
||||
dir, fn := filepath.Split(path)
|
||||
lockfn := filepath.Join(dir, fn)
|
||||
|
||||
lockfile, err := os.OpenFile(lockfn, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0600)
|
||||
if e, ok := err.(*os.PathError); ok && e.Error == os.EEXIST {
|
||||
content, err := ioutil.ReadFile(lockfn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pid, err := strconv.Atoi(string(content))
|
||||
if err == nil {
|
||||
if syscall.Kill(pid, 0) == 0 {
|
||||
return ErrLocked
|
||||
}
|
||||
}
|
||||
|
||||
lockfile, err = ioutil.TempFile(dir, "lock")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = lockfile.WriteString(strconv.Itoa(syscall.Getpid()))
|
||||
if err != nil {
|
||||
lockfile.Close()
|
||||
return ErrLockAcquirement
|
||||
}
|
||||
|
||||
curfn := lockfile.Name()
|
||||
|
||||
err = lockfile.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = os.Rename(curfn, lockfn)
|
||||
if err != nil {
|
||||
os.Remove(curfn)
|
||||
return ErrLockAcquirement
|
||||
}
|
||||
} else if err != nil {
|
||||
return err
|
||||
} else {
|
||||
_, err = lockfile.WriteString(strconv.Itoa(syscall.Getpid()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
lockfile.Close()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func AcquireLockFile(path string) error {
|
||||
dir, fn := filepath.Split(path)
|
||||
lockfn := filepath.Join(dir, fn)
|
||||
|
||||
lockfile, err := os.OpenFile(lockfn, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0600)
|
||||
if e, ok := err.(*os.PathError); ok && e.Err == os.EEXIST {
|
||||
content, err := ioutil.ReadFile(lockfn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pid, err := strconv.Atoi(string(content))
|
||||
if err == nil {
|
||||
if syscall.Kill(pid, 0) == 0 {
|
||||
return ErrLocked
|
||||
}
|
||||
}
|
||||
|
||||
lockfile, err = ioutil.TempFile(dir, "lock")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = lockfile.WriteString(strconv.Itoa(syscall.Getpid()))
|
||||
if err != nil {
|
||||
lockfile.Close()
|
||||
return ErrLockAcquirement
|
||||
}
|
||||
|
||||
curfn := lockfile.Name()
|
||||
|
||||
err = lockfile.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = os.Rename(curfn, lockfn)
|
||||
if err != nil {
|
||||
os.Remove(curfn)
|
||||
return ErrLockAcquirement
|
||||
}
|
||||
} else if err != nil {
|
||||
return err
|
||||
} else {
|
||||
_, err = lockfile.WriteString(strconv.Itoa(syscall.Getpid()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
lockfile.Close()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Release lockfile at path.
|
||||
func ReleaseLockFile(path string) os.Error {
|
||||
return os.Remove(path)
|
||||
}
|
||||
func ReleaseLockFile(path string) error {
|
||||
return os.Remove(path)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,29 +1,26 @@
|
|||
// Copyright (c) 2011 The Grumble Authors
|
||||
// The use of this source code is goverened by a BSD-style
|
||||
// license that can be found in the LICENSE-file.
|
||||
|
||||
package blobstore
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
const (
|
||||
FILE_FLAG_DELETE_ON_CLOSE = 0x04000000
|
||||
)
|
||||
|
||||
|
||||
package blobstore
|
||||
|
||||
import "syscall"
|
||||
|
||||
const (
|
||||
FILE_FLAG_DELETE_ON_CLOSE = 0x04000000
|
||||
)
|
||||
|
||||
// Acquire a lockfile at path.
|
||||
func AcquireLockFile(path string) os.Error {
|
||||
handle, _ := syscall.CreateFile(syscall.StringToUTF16Ptr(path), syscall.GENERIC_WRITE, 0, nil, syscall.CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, 0)
|
||||
if handle < 0 {
|
||||
return ErrLocked
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func AcquireLockFile(path string) error {
|
||||
handle, _ := syscall.CreateFile(syscall.StringToUTF16Ptr(path), syscall.GENERIC_WRITE, 0, nil, syscall.CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, 0)
|
||||
if handle < 0 {
|
||||
return ErrLocked
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Release the lockfile at path.
|
||||
func ReleaseLockFile(path string) os.Error {
|
||||
func ReleaseLockFile(path string) error {
|
||||
// No-op because we use FLAG_DELETE_ON_CLOSE.
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ package cryptstate
|
|||
import (
|
||||
"crypto/aes"
|
||||
"crypto/rand"
|
||||
"os"
|
||||
"errors"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
|
@ -20,27 +20,27 @@ type CryptState struct {
|
|||
DecryptIV [aes.BlockSize]byte
|
||||
decryptHistory [DecryptHistorySize]byte
|
||||
|
||||
LastGoodTime int64
|
||||
LastGoodTime int64
|
||||
|
||||
Good uint32
|
||||
Late uint32
|
||||
Lost uint32
|
||||
Resync uint32
|
||||
RemoteGood uint32
|
||||
RemoteLate uint32
|
||||
RemoteLost uint32
|
||||
RemoteResync uint32
|
||||
Good uint32
|
||||
Late uint32
|
||||
Lost uint32
|
||||
Resync uint32
|
||||
RemoteGood uint32
|
||||
RemoteLate uint32
|
||||
RemoteLost uint32
|
||||
RemoteResync uint32
|
||||
|
||||
cipher *aes.Cipher
|
||||
}
|
||||
|
||||
func New() (cs *CryptState, err os.Error) {
|
||||
func New() (cs *CryptState, err error) {
|
||||
cs = new(CryptState)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (cs *CryptState) GenerateKey() (err os.Error) {
|
||||
func (cs *CryptState) GenerateKey() (err error) {
|
||||
rand.Read(cs.RawKey[0:])
|
||||
rand.Read(cs.EncryptIV[0:])
|
||||
rand.Read(cs.DecryptIV[0:])
|
||||
|
|
@ -53,19 +53,19 @@ func (cs *CryptState) GenerateKey() (err os.Error) {
|
|||
return
|
||||
}
|
||||
|
||||
func (cs *CryptState) SetKey(key []byte, eiv []byte, div []byte) (err os.Error) {
|
||||
func (cs *CryptState) SetKey(key []byte, eiv []byte, div []byte) (err error) {
|
||||
if copy(cs.RawKey[0:], key[0:]) != aes.BlockSize {
|
||||
err = os.NewError("Unable to copy key")
|
||||
err = errors.New("Unable to copy key")
|
||||
return
|
||||
}
|
||||
|
||||
if copy(cs.EncryptIV[0:], eiv[0:]) != aes.BlockSize {
|
||||
err = os.NewError("Unable to copy EIV")
|
||||
err = errors.New("Unable to copy EIV")
|
||||
return
|
||||
}
|
||||
|
||||
if copy(cs.DecryptIV[0:], div[0:]) != aes.BlockSize {
|
||||
err = os.NewError("Unable to copy DIV")
|
||||
err = errors.New("Unable to copy DIV")
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -77,15 +77,15 @@ func (cs *CryptState) SetKey(key []byte, eiv []byte, div []byte) (err os.Error)
|
|||
return
|
||||
}
|
||||
|
||||
func (cs *CryptState) Decrypt(dst, src []byte) (err os.Error) {
|
||||
func (cs *CryptState) Decrypt(dst, src []byte) (err error) {
|
||||
if len(src) < 4 {
|
||||
err = os.NewError("Crypted length too short to decrypt")
|
||||
err = errors.New("Crypted length too short to decrypt")
|
||||
return
|
||||
}
|
||||
|
||||
plain_len := len(src) - 4
|
||||
if len(dst) != plain_len {
|
||||
err = os.NewError("plain_len and src len mismatch")
|
||||
err = errors.New("plain_len and src len mismatch")
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -100,7 +100,7 @@ func (cs *CryptState) Decrypt(dst, src []byte) (err os.Error) {
|
|||
restore = false
|
||||
|
||||
if copy(saveiv[0:], cs.DecryptIV[0:]) != aes.BlockSize {
|
||||
err = os.NewError("Copy failed")
|
||||
err = errors.New("Copy failed")
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -117,7 +117,7 @@ func (cs *CryptState) Decrypt(dst, src []byte) (err os.Error) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
err = os.NewError("invalid ivbyte")
|
||||
err = errors.New("invalid ivbyte")
|
||||
}
|
||||
} else {
|
||||
// Out of order or repeat
|
||||
|
|
@ -162,13 +162,13 @@ func (cs *CryptState) Decrypt(dst, src []byte) (err os.Error) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
err = os.NewError("No matching ivbyte")
|
||||
err = errors.New("No matching ivbyte")
|
||||
return
|
||||
}
|
||||
|
||||
if cs.decryptHistory[cs.DecryptIV[0]] == cs.DecryptIV[0] {
|
||||
if copy(cs.DecryptIV[0:], saveiv[0:]) != aes.BlockSize {
|
||||
err = os.NewError("Failed to copy aes.BlockSize bytes")
|
||||
err = errors.New("Failed to copy aes.BlockSize bytes")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
@ -179,10 +179,10 @@ func (cs *CryptState) Decrypt(dst, src []byte) (err os.Error) {
|
|||
for i := 0; i < 3; i++ {
|
||||
if tag[i] != src[i+1] {
|
||||
if copy(cs.DecryptIV[0:], saveiv[0:]) != aes.BlockSize {
|
||||
err = os.NewError("Error while trying to recover from error")
|
||||
err = errors.New("Error while trying to recover from error")
|
||||
return
|
||||
}
|
||||
err = os.NewError("tag mismatch")
|
||||
err = errors.New("tag mismatch")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
@ -191,7 +191,7 @@ func (cs *CryptState) Decrypt(dst, src []byte) (err os.Error) {
|
|||
|
||||
if restore {
|
||||
if copy(cs.DecryptIV[0:], saveiv[0:]) != aes.BlockSize {
|
||||
err = os.NewError("Error while trying to recover IV")
|
||||
err = errors.New("Error while trying to recover IV")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
@ -262,7 +262,7 @@ func times3(block []byte) {
|
|||
block[aes.BlockSize-1] ^= ((block[aes.BlockSize-1] << 1) ^ (carry * 135))
|
||||
}
|
||||
|
||||
func (cs *CryptState) OCBEncrypt(dst []byte, src []byte, nonce []byte, tag []byte) (err os.Error) {
|
||||
func (cs *CryptState) OCBEncrypt(dst []byte, src []byte, nonce []byte, tag []byte) (err error) {
|
||||
var delta [aes.BlockSize]byte
|
||||
var checksum [aes.BlockSize]byte
|
||||
var tmp [aes.BlockSize]byte
|
||||
|
|
@ -292,17 +292,17 @@ func (cs *CryptState) OCBEncrypt(dst []byte, src []byte, nonce []byte, tag []byt
|
|||
cs.cipher.Encrypt(pad[0:], tmp[0:])
|
||||
copied := copy(tmp[0:], src[off:])
|
||||
if copied != remain {
|
||||
err = os.NewError("Copy failed")
|
||||
err = errors.New("Copy failed")
|
||||
return
|
||||
}
|
||||
if copy(tmp[copied:], pad[copied:]) != (aes.BlockSize - remain) {
|
||||
err = os.NewError("Copy failed")
|
||||
err = errors.New("Copy failed")
|
||||
return
|
||||
}
|
||||
xor(checksum[0:], checksum[0:], tmp[0:])
|
||||
xor(tmp[0:], pad[0:], tmp[0:])
|
||||
if copy(dst[off:], tmp[0:]) != remain {
|
||||
err = os.NewError("Copy failed")
|
||||
err = errors.New("Copy failed")
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -313,7 +313,7 @@ func (cs *CryptState) OCBEncrypt(dst []byte, src []byte, nonce []byte, tag []byt
|
|||
return
|
||||
}
|
||||
|
||||
func (cs *CryptState) OCBDecrypt(plain []byte, encrypted []byte, nonce []byte, tag []byte) (err os.Error) {
|
||||
func (cs *CryptState) OCBDecrypt(plain []byte, encrypted []byte, nonce []byte, tag []byte) (err error) {
|
||||
var checksum [aes.BlockSize]byte
|
||||
var delta [aes.BlockSize]byte
|
||||
var tmp [aes.BlockSize]byte
|
||||
|
|
@ -344,14 +344,14 @@ func (cs *CryptState) OCBDecrypt(plain []byte, encrypted []byte, nonce []byte, t
|
|||
zeros(tmp[0:])
|
||||
copied := copy(tmp[0:remain], encrypted[off:off+remain])
|
||||
if copied != remain {
|
||||
err = os.NewError("Copy failed")
|
||||
err = errors.New("Copy failed")
|
||||
return
|
||||
}
|
||||
xor(tmp[0:], tmp[0:], pad[0:])
|
||||
xor(checksum[0:], checksum[0:], tmp[0:])
|
||||
copied = copy(plain[off:off+remain], tmp[0:remain])
|
||||
if copied != remain {
|
||||
err = os.NewError("Copy failed")
|
||||
err = errors.New("Copy failed")
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,18 +4,18 @@
|
|||
|
||||
package freezer
|
||||
|
||||
import "os"
|
||||
import "errors"
|
||||
|
||||
// Writer errors
|
||||
var (
|
||||
ErrTxGroupFull = os.NewError("transction group is full")
|
||||
ErrTxGroupValueTooBig = os.NewError("value too big to put inside the txgroup")
|
||||
ErrTxGroupFull = errors.New("transction group is full")
|
||||
ErrTxGroupValueTooBig = errors.New("value too big to put inside the txgroup")
|
||||
)
|
||||
|
||||
// Walker errors
|
||||
var (
|
||||
ErrUnexpectedEndOfRecord = os.NewError("unexpected end of record")
|
||||
ErrCRC32Mismatch = os.NewError("CRC32 mismatch")
|
||||
ErrRemainingBytesForRecord = os.NewError("remaining bytes in record")
|
||||
ErrRecordTooBig = os.NewError("the record in the file is too big")
|
||||
)
|
||||
ErrUnexpectedEndOfRecord = errors.New("unexpected end of record")
|
||||
ErrCRC32Mismatch = errors.New("CRC32 mismatch")
|
||||
ErrRemainingBytesForRecord = errors.New("remaining bytes in record")
|
||||
ErrRecordTooBig = errors.New("the record in the file is too big")
|
||||
)
|
||||
|
|
|
|||
|
|
@ -15,9 +15,9 @@ import (
|
|||
"testing"
|
||||
)
|
||||
|
||||
var testValues []interface{} = []interface{} {
|
||||
var testValues []interface{} = []interface{}{
|
||||
&ConfigKeyValuePair{Key: proto.String("Foo")},
|
||||
&BanList{Bans: []*Ban{ &Ban{ Mask: proto.Uint32(32) } } },
|
||||
&BanList{Bans: []*Ban{&Ban{Mask: proto.Uint32(32)}}},
|
||||
&User{Id: proto.Uint32(0), Name: proto.String("SuperUser")},
|
||||
&UserRemove{Id: proto.Uint32(0)},
|
||||
&Channel{Id: proto.Uint32(0), Name: proto.String("RootChannel")},
|
||||
|
|
@ -25,7 +25,7 @@ var testValues []interface{} = []interface{} {
|
|||
}
|
||||
|
||||
// Generate a byet slice representing an entry in a Tx record
|
||||
func genTxValue(kind uint16, val []byte) (chunk []byte, crc32sum uint32, err os.Error) {
|
||||
func genTxValue(kind uint16, val []byte) (chunk []byte, crc32sum uint32, err error) {
|
||||
buf := new(bytes.Buffer)
|
||||
|
||||
err = binary.Write(buf, binary.LittleEndian, kind)
|
||||
|
|
@ -53,10 +53,10 @@ func genTxValue(kind uint16, val []byte) (chunk []byte, crc32sum uint32, err os.
|
|||
}
|
||||
|
||||
// Generate the header of a Tx record
|
||||
func genTestCaseHeader(chunk []byte, numops uint32, crc32sum uint32) (r io.Reader, err os.Error) {
|
||||
func genTestCaseHeader(chunk []byte, numops uint32, crc32sum uint32) (r io.Reader, err error) {
|
||||
buf := new(bytes.Buffer)
|
||||
|
||||
err = binary.Write(buf, binary.LittleEndian, uint32(4 + 4 + len(chunk)))
|
||||
err = binary.Write(buf, binary.LittleEndian, uint32(4+4+len(chunk)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -101,9 +101,9 @@ func TestLogging(t *testing.T) {
|
|||
defer os.Remove("logging.log")
|
||||
|
||||
for _, val := range testValues {
|
||||
err = l.Put(val)
|
||||
err = l.Put(val)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
@ -117,13 +117,13 @@ func TestLogging(t *testing.T) {
|
|||
i := 0
|
||||
for {
|
||||
entries, err := walker.Next()
|
||||
if err == os.EOF {
|
||||
if err == io.EOF {
|
||||
break
|
||||
} else if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
if len(entries) != 1 {
|
||||
if len(entries) != 1 {
|
||||
t.Error("> 1 entry in log tx")
|
||||
return
|
||||
}
|
||||
|
|
@ -157,7 +157,7 @@ func TestCRC32MismatchLog(t *testing.T) {
|
|||
t.Errorf("exepcted CRC32 mismatch, got %v", err)
|
||||
}
|
||||
_, err = walker.Next()
|
||||
if err != os.EOF {
|
||||
if err != io.EOF {
|
||||
t.Errorf("expected EOF, got %v", err)
|
||||
}
|
||||
}
|
||||
|
|
@ -187,7 +187,7 @@ func TestUnknownTypeDecode(t *testing.T) {
|
|||
t.Errorf("expected empty entries and non-nil err (got %v entries and %v)", len(entries), err)
|
||||
}
|
||||
_, err = walker.Next()
|
||||
if err != os.EOF {
|
||||
if err != io.EOF {
|
||||
t.Errorf("expected EOF, got %v", err)
|
||||
}
|
||||
}
|
||||
|
|
@ -223,7 +223,7 @@ func TestTrailingBytesTxRecord(t *testing.T) {
|
|||
}
|
||||
|
||||
_, err = walker.Next()
|
||||
if err != os.EOF {
|
||||
if err != io.EOF {
|
||||
t.Errorf("expected EOF, got %v", err)
|
||||
}
|
||||
}
|
||||
|
|
@ -232,7 +232,7 @@ func TestTrailingBytesTxRecord(t *testing.T) {
|
|||
// A TxRecord can hold 255 entries, and each of those can be
|
||||
// up to 16KB.
|
||||
func TestTooBigTxRecord(t *testing.T) {
|
||||
bigValue := make([]byte, math.MaxUint16*math.MaxUint8 + 4)
|
||||
bigValue := make([]byte, math.MaxUint16*math.MaxUint8+4)
|
||||
r, err := genTestCaseHeader(bigValue, 1, 0)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
|
|
@ -242,7 +242,7 @@ func TestTooBigTxRecord(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
|
||||
_, err = walker.Next()
|
||||
if err != ErrRecordTooBig {
|
||||
t.Errorf("expected ErrRecordTooBig, got %v", err)
|
||||
|
|
@ -265,7 +265,7 @@ func TestTxGroupCapacityEnforcement(t *testing.T) {
|
|||
}
|
||||
|
||||
for i := 0; i <= 255; i++ {
|
||||
entry := testValues[i % len(testValues)]
|
||||
entry := testValues[i%len(testValues)]
|
||||
err = tx.Put(entry)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
|
|
@ -277,4 +277,4 @@ func TestTxGroupCapacityEnforcement(t *testing.T) {
|
|||
if err != ErrTxGroupFull {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ import (
|
|||
|
||||
// Checks whether the error err is an EOF
|
||||
// error.
|
||||
func isEOF(err os.Error) bool {
|
||||
if err == os.EOF || err == io.ErrUnexpectedEOF {
|
||||
func isEOF(err error) bool {
|
||||
if err == io.EOF || err == io.ErrUnexpectedEOF {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
@ -52,9 +52,9 @@ func newTxReader(r io.Reader) *txReader {
|
|||
|
||||
// walkReader's Read method. Reads from walkReader's Reader
|
||||
// and checksums while reading.
|
||||
func (txr *txReader) Read(p []byte) (n int, err os.Error) {
|
||||
func (txr *txReader) Read(p []byte) (n int, err error) {
|
||||
n, err = txr.r.Read(p)
|
||||
if err != nil && err != os.EOF {
|
||||
if err != nil && err != io.EOF {
|
||||
return
|
||||
}
|
||||
txr.consumed += n
|
||||
|
|
@ -80,7 +80,7 @@ func (txr *txReader) Consumed() int {
|
|||
}
|
||||
|
||||
// Create a new Walker that iterates over the entries of the given log file.
|
||||
func NewFileWalker(fn string) (walker *Walker, err os.Error) {
|
||||
func NewFileWalker(fn string) (walker *Walker, err error) {
|
||||
f, err := os.Open(fn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -93,7 +93,7 @@ func NewFileWalker(fn string) (walker *Walker, err os.Error) {
|
|||
}
|
||||
|
||||
// Create a new Walker that iterates over the log entries of a given Reader.
|
||||
func NewReaderWalker(r io.Reader) (walker *Walker, err os.Error) {
|
||||
func NewReaderWalker(r io.Reader) (walker *Walker, err error) {
|
||||
walker = new(Walker)
|
||||
walker.r = r
|
||||
return walker, nil
|
||||
|
|
@ -108,18 +108,18 @@ func NewReaderWalker(r io.Reader) (walker *Walker, err os.Error) {
|
|||
//
|
||||
// On error, Next returns a nil slice and a non-nil err.
|
||||
// When the end of the file is reached, Next returns nil, os.EOF.
|
||||
func (walker *Walker) Next() (entries []interface{}, err os.Error) {
|
||||
func (walker *Walker) Next() (entries []interface{}, err error) {
|
||||
var (
|
||||
remainBytes uint32
|
||||
remainOps uint32
|
||||
crcsum uint32
|
||||
kind uint16
|
||||
length uint16
|
||||
remainBytes uint32
|
||||
remainOps uint32
|
||||
crcsum uint32
|
||||
kind uint16
|
||||
length uint16
|
||||
)
|
||||
|
||||
err = binary.Read(walker.r, binary.LittleEndian, &remainBytes)
|
||||
if isEOF(err) {
|
||||
return nil, os.EOF
|
||||
return nil, io.EOF
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -128,7 +128,7 @@ func (walker *Walker) Next() (entries []interface{}, err os.Error) {
|
|||
return nil, ErrUnexpectedEndOfRecord
|
||||
}
|
||||
if remainBytes-8 > math.MaxUint8*math.MaxUint16 {
|
||||
return nil, ErrRecordTooBig
|
||||
return nil, ErrRecordTooBig
|
||||
}
|
||||
|
||||
err = binary.Read(walker.r, binary.LittleEndian, &remainOps)
|
||||
|
|
@ -140,7 +140,7 @@ func (walker *Walker) Next() (entries []interface{}, err os.Error) {
|
|||
|
||||
err = binary.Read(walker.r, binary.LittleEndian, &crcsum)
|
||||
if isEOF(err) {
|
||||
return nil, ErrUnexpectedEndOfRecord
|
||||
return nil, ErrUnexpectedEndOfRecord
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -151,14 +151,14 @@ func (walker *Walker) Next() (entries []interface{}, err os.Error) {
|
|||
for remainOps > 0 {
|
||||
err = binary.Read(reader, binary.LittleEndian, &kind)
|
||||
if isEOF(err) {
|
||||
break
|
||||
break
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = binary.Read(reader, binary.LittleEndian, &length)
|
||||
if isEOF(err) {
|
||||
break
|
||||
break
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -166,7 +166,7 @@ func (walker *Walker) Next() (entries []interface{}, err os.Error) {
|
|||
buf := make([]byte, length)
|
||||
_, err = io.ReadFull(reader, buf)
|
||||
if isEOF(err) {
|
||||
break
|
||||
break
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,21 +37,21 @@ import (
|
|||
// whole transaction group. In case of a failure, none of the
|
||||
// entries of a transaction will be applied.
|
||||
type Log struct {
|
||||
wc io.WriteCloser
|
||||
wc io.WriteCloser
|
||||
}
|
||||
|
||||
// Type LogTx represents a transaction in the log.
|
||||
// Transactions can be used to group several changes into an
|
||||
// atomic entity in the log file.
|
||||
type LogTx struct {
|
||||
log *Log
|
||||
crc hash.Hash32
|
||||
buf *bytes.Buffer
|
||||
numops int
|
||||
log *Log
|
||||
crc hash.Hash32
|
||||
buf *bytes.Buffer
|
||||
numops int
|
||||
}
|
||||
|
||||
// Create a new log file
|
||||
func NewLogFile(fn string) (*Log, os.Error) {
|
||||
func NewLogFile(fn string) (*Log, error) {
|
||||
f, err := os.Create(fn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -64,7 +64,7 @@ func NewLogFile(fn string) (*Log, os.Error) {
|
|||
}
|
||||
|
||||
// Close a Log
|
||||
func (log *Log) Close() os.Error {
|
||||
func (log *Log) Close() error {
|
||||
return log.wc.Close()
|
||||
}
|
||||
|
||||
|
|
@ -73,7 +73,7 @@ func (log *Log) Close() os.Error {
|
|||
// This method implicitly creates a transaction
|
||||
// group for this single Put operation. It is merely
|
||||
// a convenience wrapper.
|
||||
func (log *Log) Put(value interface{}) (err os.Error) {
|
||||
func (log *Log) Put(value interface{}) (err error) {
|
||||
tx := log.BeginTx()
|
||||
err = tx.Put(value)
|
||||
if err != nil {
|
||||
|
|
@ -94,7 +94,7 @@ func (log *Log) BeginTx() *LogTx {
|
|||
// Append a log entry to the transaction.
|
||||
// The transaction's log entries will not be persisted to
|
||||
// the log until the Commit has been called on the transaction.
|
||||
func (tx *LogTx) Put(value interface{}) (err os.Error) {
|
||||
func (tx *LogTx) Put(value interface{}) (err error) {
|
||||
var (
|
||||
buf []byte
|
||||
kind typeKind
|
||||
|
|
@ -155,17 +155,17 @@ func (tx *LogTx) Put(value interface{}) (err os.Error) {
|
|||
return err
|
||||
}
|
||||
|
||||
tx.numops += 1;
|
||||
tx.numops += 1
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Commit all changes of the transaction to the log
|
||||
// as a single atomic entry.
|
||||
func (tx *LogTx) Commit() (err os.Error) {
|
||||
func (tx *LogTx) Commit() (err error) {
|
||||
buf := new(bytes.Buffer)
|
||||
|
||||
err = binary.Write(buf, binary.LittleEndian, uint32(4 + 4 + tx.buf.Len()))
|
||||
err = binary.Write(buf, binary.LittleEndian, uint32(4+4+tx.buf.Len()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -191,4 +191,4 @@ func (tx *LogTx) Commit() (err os.Error) {
|
|||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ package htmlfilter
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
"errors"
|
||||
"io"
|
||||
"strings"
|
||||
"xml"
|
||||
)
|
||||
|
|
@ -24,12 +25,12 @@ var defaultOptions Options = Options{
|
|||
}
|
||||
|
||||
var (
|
||||
ErrExceedsTextMessageLength = os.NewError("Exceeds text message length")
|
||||
ErrExceedsImageMessageLength = os.NewError("Exceeds image message length")
|
||||
ErrExceedsTextMessageLength = errors.New("Exceeds text message length")
|
||||
ErrExceedsImageMessageLength = errors.New("Exceeds image message length")
|
||||
)
|
||||
|
||||
// Filter text according to options.
|
||||
func Filter(text string, options *Options) (filtered string, err os.Error) {
|
||||
func Filter(text string, options *Options) (filtered string, err error) {
|
||||
// This function filters incoming text from clients according to the three options:
|
||||
//
|
||||
// StripHTML:
|
||||
|
|
@ -64,7 +65,7 @@ func Filter(text string, options *Options) (filtered string, err os.Error) {
|
|||
parser.Entity = xml.HTMLEntity
|
||||
for {
|
||||
tok, err := parser.Token()
|
||||
if err == os.EOF {
|
||||
if err == io.EOF {
|
||||
break
|
||||
} else if err != nil {
|
||||
return "", err
|
||||
|
|
@ -117,7 +118,7 @@ func Filter(text string, options *Options) (filtered string, err os.Error) {
|
|||
parser.Entity = xml.HTMLEntity
|
||||
for {
|
||||
tok, err := parser.Token()
|
||||
if err == os.EOF {
|
||||
if err == io.EOF {
|
||||
break
|
||||
} else if err != nil {
|
||||
return "", err
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ func (cfg *Config) Set(key string, value string) {
|
|||
func (cfg *Config) Reset(key string) {
|
||||
cfg.mutex.Lock()
|
||||
defer cfg.mutex.Unlock()
|
||||
cfg.cfgMap[key] = "", false
|
||||
delete(cfg.cfgMap, key)
|
||||
}
|
||||
|
||||
// Get the value of a specific config key encoded as a string
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ func (pool *SessionPool) Reclaim(id uint32) {
|
|||
if !inUse {
|
||||
panic("Attempt to reclaim invalid session ID")
|
||||
}
|
||||
pool.used[id] = false, false
|
||||
delete(pool.used, id)
|
||||
}
|
||||
|
||||
pool.unused = append(pool.unused, id)
|
||||
|
|
|
|||
|
|
@ -28,17 +28,18 @@ static int my_bind_blob(sqlite3_stmt *stmt, int n, void *p, int np) {
|
|||
import "C"
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"unsafe"
|
||||
"time"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type Errno int
|
||||
|
||||
func (e Errno) String() string {
|
||||
func (e Errno) Error() string {
|
||||
s := errText[e]
|
||||
if s == "" {
|
||||
return fmt.Sprintf("errno %d", int(e))
|
||||
|
|
@ -47,76 +48,76 @@ func (e Errno) String() string {
|
|||
}
|
||||
|
||||
var (
|
||||
ErrError os.Error = Errno(1) // /* SQL error or missing database */
|
||||
ErrInternal os.Error = Errno(2) // /* Internal logic error in SQLite */
|
||||
ErrPerm os.Error = Errno(3) // /* Access permission denied */
|
||||
ErrAbort os.Error = Errno(4) // /* Callback routine requested an abort */
|
||||
ErrBusy os.Error = Errno(5) // /* The database file is locked */
|
||||
ErrLocked os.Error = Errno(6) // /* A table in the database is locked */
|
||||
ErrNoMem os.Error = Errno(7) // /* A malloc() failed */
|
||||
ErrReadOnly os.Error = Errno(8) // /* Attempt to write a readonly database */
|
||||
ErrInterrupt os.Error = Errno(9) // /* Operation terminated by sqlite3_interrupt()*/
|
||||
ErrIOErr os.Error = Errno(10) // /* Some kind of disk I/O error occurred */
|
||||
ErrCorrupt os.Error = Errno(11) // /* The database disk image is malformed */
|
||||
ErrFull os.Error = Errno(13) // /* Insertion failed because database is full */
|
||||
ErrCantOpen os.Error = Errno(14) // /* Unable to open the database file */
|
||||
ErrEmpty os.Error = Errno(16) // /* Database is empty */
|
||||
ErrSchema os.Error = Errno(17) // /* The database schema changed */
|
||||
ErrTooBig os.Error = Errno(18) // /* String or BLOB exceeds size limit */
|
||||
ErrConstraint os.Error = Errno(19) // /* Abort due to constraint violation */
|
||||
ErrMismatch os.Error = Errno(20) // /* Data type mismatch */
|
||||
ErrMisuse os.Error = Errno(21) // /* Library used incorrectly */
|
||||
ErrNolfs os.Error = Errno(22) // /* Uses OS features not supported on host */
|
||||
ErrAuth os.Error = Errno(23) // /* Authorization denied */
|
||||
ErrFormat os.Error = Errno(24) // /* Auxiliary database format error */
|
||||
ErrRange os.Error = Errno(25) // /* 2nd parameter to sqlite3_bind out of range */
|
||||
ErrNotDB os.Error = Errno(26) // /* File opened that is not a database file */
|
||||
Row = Errno(100) // /* sqlite3_step() has another row ready */
|
||||
Done = Errno(101) // /* sqlite3_step() has finished executing */
|
||||
ErrError error = Errno(1) // /* SQL error or missing database */
|
||||
ErrInternal error = Errno(2) // /* Internal logic error in SQLite */
|
||||
ErrPerm error = Errno(3) // /* Access permission denied */
|
||||
ErrAbort error = Errno(4) // /* Callback routine requested an abort */
|
||||
ErrBusy error = Errno(5) // /* The database file is locked */
|
||||
ErrLocked error = Errno(6) // /* A table in the database is locked */
|
||||
ErrNoMem error = Errno(7) // /* A malloc() failed */
|
||||
ErrReadOnly error = Errno(8) // /* Attempt to write a readonly database */
|
||||
ErrInterrupt error = Errno(9) // /* Operation terminated by sqlite3_interrupt()*/
|
||||
ErrIOErr error = Errno(10) // /* Some kind of disk I/O error occurred */
|
||||
ErrCorrupt error = Errno(11) // /* The database disk image is malformed */
|
||||
ErrFull error = Errno(13) // /* Insertion failed because database is full */
|
||||
ErrCantOpen error = Errno(14) // /* Unable to open the database file */
|
||||
ErrEmpty error = Errno(16) // /* Database is empty */
|
||||
ErrSchema error = Errno(17) // /* The database schema changed */
|
||||
ErrTooBig error = Errno(18) // /* String or BLOB exceeds size limit */
|
||||
ErrConstraint error = Errno(19) // /* Abort due to constraint violation */
|
||||
ErrMismatch error = Errno(20) // /* Data type mismatch */
|
||||
ErrMisuse error = Errno(21) // /* Library used incorrectly */
|
||||
ErrNolfs error = Errno(22) // /* Uses OS features not supported on host */
|
||||
ErrAuth error = Errno(23) // /* Authorization denied */
|
||||
ErrFormat error = Errno(24) // /* Auxiliary database format error */
|
||||
ErrRange error = Errno(25) // /* 2nd parameter to sqlite3_bind out of range */
|
||||
ErrNotDB error = Errno(26) // /* File opened that is not a database file */
|
||||
Row = Errno(100) // /* sqlite3_step() has another row ready */
|
||||
Done = Errno(101) // /* sqlite3_step() has finished executing */
|
||||
)
|
||||
|
||||
var errText = map[Errno]string {
|
||||
1: "SQL error or missing database",
|
||||
2: "Internal logic error in SQLite",
|
||||
3: "Access permission denied",
|
||||
4: "Callback routine requested an abort",
|
||||
5: "The database file is locked",
|
||||
6: "A table in the database is locked",
|
||||
7: "A malloc() failed",
|
||||
8: "Attempt to write a readonly database",
|
||||
9: "Operation terminated by sqlite3_interrupt()*/",
|
||||
10: "Some kind of disk I/O error occurred",
|
||||
11: "The database disk image is malformed",
|
||||
12: "NOT USED. Table or record not found",
|
||||
13: "Insertion failed because database is full",
|
||||
14: "Unable to open the database file",
|
||||
15: "NOT USED. Database lock protocol error",
|
||||
16: "Database is empty",
|
||||
17: "The database schema changed",
|
||||
18: "String or BLOB exceeds size limit",
|
||||
19: "Abort due to constraint violation",
|
||||
20: "Data type mismatch",
|
||||
21: "Library used incorrectly",
|
||||
22: "Uses OS features not supported on host",
|
||||
23: "Authorization denied",
|
||||
24: "Auxiliary database format error",
|
||||
25: "2nd parameter to sqlite3_bind out of range",
|
||||
26: "File opened that is not a database file",
|
||||
var errText = map[Errno]string{
|
||||
1: "SQL error or missing database",
|
||||
2: "Internal logic error in SQLite",
|
||||
3: "Access permission denied",
|
||||
4: "Callback routine requested an abort",
|
||||
5: "The database file is locked",
|
||||
6: "A table in the database is locked",
|
||||
7: "A malloc() failed",
|
||||
8: "Attempt to write a readonly database",
|
||||
9: "Operation terminated by sqlite3_interrupt()*/",
|
||||
10: "Some kind of disk I/O error occurred",
|
||||
11: "The database disk image is malformed",
|
||||
12: "NOT USED. Table or record not found",
|
||||
13: "Insertion failed because database is full",
|
||||
14: "Unable to open the database file",
|
||||
15: "NOT USED. Database lock protocol error",
|
||||
16: "Database is empty",
|
||||
17: "The database schema changed",
|
||||
18: "String or BLOB exceeds size limit",
|
||||
19: "Abort due to constraint violation",
|
||||
20: "Data type mismatch",
|
||||
21: "Library used incorrectly",
|
||||
22: "Uses OS features not supported on host",
|
||||
23: "Authorization denied",
|
||||
24: "Auxiliary database format error",
|
||||
25: "2nd parameter to sqlite3_bind out of range",
|
||||
26: "File opened that is not a database file",
|
||||
100: "sqlite3_step() has another row ready",
|
||||
101: "sqlite3_step() has finished executing",
|
||||
}
|
||||
|
||||
func (c *Conn) error(rv C.int) os.Error {
|
||||
func (c *Conn) error(rv C.int) error {
|
||||
if c == nil || c.db == nil {
|
||||
return os.NewError("nil sqlite database")
|
||||
return errors.New("nil sqlite database")
|
||||
}
|
||||
if rv == 0 {
|
||||
return nil
|
||||
}
|
||||
if rv == 21 { // misuse
|
||||
if rv == 21 { // misuse
|
||||
return Errno(rv)
|
||||
}
|
||||
return os.NewError(Errno(rv).String() + ": " + C.GoString(C.sqlite3_errmsg(c.db)))
|
||||
return errors.New(Errno(rv).Error() + ": " + C.GoString(C.sqlite3_errmsg(c.db)))
|
||||
}
|
||||
|
||||
type Conn struct {
|
||||
|
|
@ -124,33 +125,33 @@ type Conn struct {
|
|||
}
|
||||
|
||||
func Version() string {
|
||||
p := C.sqlite3_libversion();
|
||||
return C.GoString(p);
|
||||
p := C.sqlite3_libversion()
|
||||
return C.GoString(p)
|
||||
}
|
||||
|
||||
func Open(filename string) (*Conn, os.Error) {
|
||||
func Open(filename string) (*Conn, error) {
|
||||
if C.sqlite3_threadsafe() == 0 {
|
||||
return nil, os.NewError("sqlite library was not compiled for thread-safe operation")
|
||||
return nil, errors.New("sqlite library was not compiled for thread-safe operation")
|
||||
}
|
||||
|
||||
var db *C.sqlite3
|
||||
name := C.CString(filename)
|
||||
defer C.free(unsafe.Pointer(name))
|
||||
rv := C.sqlite3_open_v2(name, &db,
|
||||
C.SQLITE_OPEN_FULLMUTEX |
|
||||
C.SQLITE_OPEN_READWRITE |
|
||||
C.SQLITE_OPEN_CREATE,
|
||||
C.SQLITE_OPEN_FULLMUTEX|
|
||||
C.SQLITE_OPEN_READWRITE|
|
||||
C.SQLITE_OPEN_CREATE,
|
||||
nil)
|
||||
if rv != 0 {
|
||||
return nil, Errno(rv)
|
||||
}
|
||||
if db == nil {
|
||||
return nil, os.NewError("sqlite succeeded without returning a database")
|
||||
return nil, errors.New("sqlite succeeded without returning a database")
|
||||
}
|
||||
return &Conn{db}, nil
|
||||
}
|
||||
|
||||
func NewBackup(dst *Conn, dstTable string, src *Conn, srcTable string) (*Backup, os.Error) {
|
||||
func NewBackup(dst *Conn, dstTable string, src *Conn, srcTable string) (*Backup, error) {
|
||||
dname := C.CString(dstTable)
|
||||
sname := C.CString(srcTable)
|
||||
defer C.free(unsafe.Pointer(dname))
|
||||
|
|
@ -164,18 +165,18 @@ func NewBackup(dst *Conn, dstTable string, src *Conn, srcTable string) (*Backup,
|
|||
}
|
||||
|
||||
type Backup struct {
|
||||
sb *C.sqlite3_backup
|
||||
sb *C.sqlite3_backup
|
||||
dst, src *Conn
|
||||
}
|
||||
|
||||
func (b *Backup) Step(npage int) os.Error {
|
||||
func (b *Backup) Step(npage int) error {
|
||||
rv := C.sqlite3_backup_step(b.sb, C.int(npage))
|
||||
if rv == 0 || Errno(rv) == ErrBusy || Errno(rv) == ErrLocked {
|
||||
return nil
|
||||
}
|
||||
return Errno(rv)
|
||||
}
|
||||
|
||||
|
||||
type BackupStatus struct {
|
||||
Remaining int
|
||||
PageCount int
|
||||
|
|
@ -185,8 +186,8 @@ func (b *Backup) Status() BackupStatus {
|
|||
return BackupStatus{int(C.sqlite3_backup_remaining(b.sb)), int(C.sqlite3_backup_pagecount(b.sb))}
|
||||
}
|
||||
|
||||
func (b *Backup) Run(npage int, sleepNs int64, c chan<- BackupStatus) os.Error {
|
||||
var err os.Error
|
||||
func (b *Backup) Run(npage int, sleepNs int64, c chan<- BackupStatus) error {
|
||||
var err error
|
||||
for {
|
||||
err = b.Step(npage)
|
||||
if err != nil {
|
||||
|
|
@ -197,10 +198,10 @@ func (b *Backup) Run(npage int, sleepNs int64, c chan<- BackupStatus) os.Error {
|
|||
}
|
||||
time.Sleep(sleepNs)
|
||||
}
|
||||
return b.dst.error(C.sqlite3_errcode(b.dst.db))
|
||||
return b.dst.error(C.sqlite3_errcode(b.dst.db))
|
||||
}
|
||||
|
||||
func (b *Backup) Close() os.Error {
|
||||
func (b *Backup) Close() error {
|
||||
if b.sb == nil {
|
||||
return os.EINVAL
|
||||
}
|
||||
|
|
@ -209,7 +210,7 @@ func (b *Backup) Close() os.Error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (c *Conn) BusyTimeout(ms int) os.Error {
|
||||
func (c *Conn) BusyTimeout(ms int) error {
|
||||
rv := C.sqlite3_busy_timeout(c.db, C.int(ms))
|
||||
if rv == 0 {
|
||||
return nil
|
||||
|
|
@ -217,7 +218,7 @@ func (c *Conn) BusyTimeout(ms int) os.Error {
|
|||
return Errno(rv)
|
||||
}
|
||||
|
||||
func (c *Conn) Exec(cmd string, args ...interface{}) os.Error {
|
||||
func (c *Conn) Exec(cmd string, args ...interface{}) error {
|
||||
s, err := c.Prepare(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -235,17 +236,17 @@ func (c *Conn) Exec(cmd string, args ...interface{}) os.Error {
|
|||
}
|
||||
|
||||
type Stmt struct {
|
||||
c *Conn
|
||||
c *Conn
|
||||
stmt *C.sqlite3_stmt
|
||||
err os.Error
|
||||
t0 int64
|
||||
sql string
|
||||
err error
|
||||
t0 int64
|
||||
sql string
|
||||
args string
|
||||
}
|
||||
|
||||
func (c *Conn) Prepare(cmd string) (*Stmt, os.Error) {
|
||||
func (c *Conn) Prepare(cmd string) (*Stmt, error) {
|
||||
if c == nil || c.db == nil {
|
||||
return nil, os.NewError("nil sqlite database")
|
||||
return nil, errors.New("nil sqlite database")
|
||||
}
|
||||
cmdstr := C.CString(cmd)
|
||||
defer C.free(unsafe.Pointer(cmdstr))
|
||||
|
|
@ -258,7 +259,7 @@ func (c *Conn) Prepare(cmd string) (*Stmt, os.Error) {
|
|||
return &Stmt{c: c, stmt: stmt, sql: cmd, t0: time.Nanoseconds()}, nil
|
||||
}
|
||||
|
||||
func (s *Stmt) Exec(args ...interface{}) os.Error {
|
||||
func (s *Stmt) Exec(args ...interface{}) error {
|
||||
s.args = fmt.Sprintf(" %v", []interface{}(args))
|
||||
rv := C.sqlite3_reset(s.stmt)
|
||||
if rv != 0 {
|
||||
|
|
@ -267,7 +268,7 @@ func (s *Stmt) Exec(args ...interface{}) os.Error {
|
|||
|
||||
n := int(C.sqlite3_bind_parameter_count(s.stmt))
|
||||
if n != len(args) {
|
||||
return os.NewError(fmt.Sprintf("incorrect argument count for Stmt.Exec: have %d want %d", len(args), n))
|
||||
return errors.New(fmt.Sprintf("incorrect argument count for Stmt.Exec: have %d want %d", len(args), n))
|
||||
}
|
||||
|
||||
for i, v := range args {
|
||||
|
|
@ -282,7 +283,7 @@ func (s *Stmt) Exec(args ...interface{}) os.Error {
|
|||
return s.c.error(rv)
|
||||
}
|
||||
continue
|
||||
|
||||
|
||||
case bool:
|
||||
if v {
|
||||
str = "1"
|
||||
|
|
@ -293,7 +294,7 @@ func (s *Stmt) Exec(args ...interface{}) os.Error {
|
|||
default:
|
||||
str = fmt.Sprint(v)
|
||||
}
|
||||
|
||||
|
||||
cstr := C.CString(str)
|
||||
rv := C.my_bind_text(s.stmt, C.int(i+1), cstr, C.int(len(str)))
|
||||
C.free(unsafe.Pointer(cstr))
|
||||
|
|
@ -304,7 +305,7 @@ func (s *Stmt) Exec(args ...interface{}) os.Error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (s *Stmt) Error() os.Error {
|
||||
func (s *Stmt) Error() error {
|
||||
return s.err
|
||||
}
|
||||
|
||||
|
|
@ -317,29 +318,29 @@ func (s *Stmt) Next() bool {
|
|||
if err != Done {
|
||||
s.err = s.c.error(rv)
|
||||
}
|
||||
return false
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *Stmt) Reset() os.Error {
|
||||
func (s *Stmt) Reset() error {
|
||||
C.sqlite3_reset(s.stmt)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Stmt) Scan(args ...interface{}) os.Error {
|
||||
func (s *Stmt) Scan(args ...interface{}) error {
|
||||
n := int(C.sqlite3_column_count(s.stmt))
|
||||
if n != len(args) {
|
||||
return os.NewError(fmt.Sprintf("incorrect argument count for Stmt.Scan: have %d want %d", len(args), n))
|
||||
return errors.New(fmt.Sprintf("incorrect argument count for Stmt.Scan: have %d want %d", len(args), n))
|
||||
}
|
||||
|
||||
|
||||
for i, v := range args {
|
||||
n := C.sqlite3_column_bytes(s.stmt, C.int(i))
|
||||
p := C.sqlite3_column_blob(s.stmt, C.int(i))
|
||||
if p == nil && n > 0 {
|
||||
return os.NewError("got nil blob")
|
||||
return errors.New("got nil blob")
|
||||
}
|
||||
var data []byte
|
||||
if n > 0 {
|
||||
data = (*[1<<30]byte)(unsafe.Pointer(p))[0:n]
|
||||
data = (*[1 << 30]byte)(unsafe.Pointer(p))[0:n]
|
||||
}
|
||||
switch v := v.(type) {
|
||||
case *[]byte:
|
||||
|
|
@ -351,23 +352,23 @@ func (s *Stmt) Scan(args ...interface{}) os.Error {
|
|||
case *int:
|
||||
x, err := strconv.Atoi(string(data))
|
||||
if err != nil {
|
||||
return os.NewError("arg " + strconv.Itoa(i) + " as int: " + err.String())
|
||||
return errors.New("arg " + strconv.Itoa(i) + " as int: " + err.Error())
|
||||
}
|
||||
*v = x
|
||||
case *int64:
|
||||
x, err := strconv.Atoi64(string(data))
|
||||
if err != nil {
|
||||
return os.NewError("arg " + strconv.Itoa(i) + " as int64: " + err.String())
|
||||
return errors.New("arg " + strconv.Itoa(i) + " as int64: " + err.Error())
|
||||
}
|
||||
*v = x
|
||||
case *float64:
|
||||
x, err := strconv.Atof64(string(data))
|
||||
if err != nil {
|
||||
return os.NewError("arg " + strconv.Itoa(i) + " as float64: " + err.String())
|
||||
return errors.New("arg " + strconv.Itoa(i) + " as float64: " + err.Error())
|
||||
}
|
||||
*v = x
|
||||
default:
|
||||
return os.NewError("unsupported type in Scan: " + reflect.TypeOf(v).String())
|
||||
return errors.New("unsupported type in Scan: " + reflect.TypeOf(v).String())
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
|
@ -381,7 +382,7 @@ func (s *Stmt) Nanoseconds() int64 {
|
|||
return time.Nanoseconds() - s.t0
|
||||
}
|
||||
|
||||
func (s *Stmt) Finalize() os.Error {
|
||||
func (s *Stmt) Finalize() error {
|
||||
rv := C.sqlite3_finalize(s.stmt)
|
||||
if rv != 0 {
|
||||
return s.c.error(rv)
|
||||
|
|
@ -389,9 +390,9 @@ func (s *Stmt) Finalize() os.Error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (c *Conn) Close() os.Error {
|
||||
func (c *Conn) Close() error {
|
||||
if c == nil || c.db == nil {
|
||||
return os.NewError("nil sqlite database")
|
||||
return errors.New("nil sqlite database")
|
||||
}
|
||||
rv := C.sqlite3_close(c.db)
|
||||
if rv != 0 {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue