Ejemplo n.º 1
0
Archivo: store.go Proyecto: andrebq/exp
func (bs *BlobStore) keyExistsInDb(id *int64, key pandora.Key) (bool, error) {
	err := bs.conn.QueryRow("select id from pgstore_blobs_ref where blobid = $1", key.Bytes()).Scan(id)
	if err == sql.ErrNoRows {
		return false, nil
	} else {
		if err != nil {
			return false, err
		}
	}
	return *id > 0, nil
}
Ejemplo n.º 2
0
Archivo: store.go Proyecto: andrebq/exp
// PutData write the contents of data and return the key used to store the data
func (bs *BlobStore) PutData(k pandora.Key, data []byte) (pandora.Key, error) {
	kw := pandora.SHA1KeyWriter{}
	kw.Write(data)
	actual := kw.Key()

	if k != nil && len(k.Bytes()) >= len(actual.Bytes()) {
		// avoid allocating outside the stack
		copy(k.Bytes(), actual.Bytes())
	} else {
		// use the heap
		k = actual
	}
	err := bs.insert(k, data)
	return k, err
}
Ejemplo n.º 3
0
Archivo: store.go Proyecto: andrebq/exp
func (ms *MessageStore) Ack(mid, lid pandora.Key, status pandora.AckStatus) error {
	return doInsideTransaction(ms.conn, func(tx querier) error {
		var id int64
		switch status {
		case pandora.StatusConfirmed, pandora.StatusRejected:
		default:
			return pandora.ErrUnableToChangeStatus
		}

		err := tx.QueryRow(`update pgstore_messages
			set status = $1, lid = null, leaseuntil = null
			where mid = $2 and lid = $3 and leaseuntil >= $4
			returning id`, status, mid.Bytes(), lid.Bytes(), time.Now()).Scan(&id)
		if err != nil {
			return err
		}
		if id == 0 {
			return pandora.ErrUnableToChangeStatus
		}
		return nil
	})
}
Ejemplo n.º 4
0
Archivo: store.go Proyecto: andrebq/exp
// if data have a Bytes() []byte method, then it is used instead of a copy
func (bs *BlobStore) insert(out pandora.Key, data []byte) error {
	var id int64
	var err error
	exists, err := bs.keyExistsInDb(&id, out)
	if err != nil {
		return err
	}
	if exists {
		return nil
	}
	return doInsideTransaction(bs.conn, func(tx querier) error {
		err := tx.QueryRow(`insert into pgstore_blobs(blobid, data) values ($1, $2) returning id`, out.Bytes(), data).Scan(&id)
		if err != nil {
			return err
		}
		_, err = tx.Exec(`insert into pgstore_blobs_ref(id, blobid, delta) values ($1, $2, $3)`, id, out.Bytes(), 0)
		if err != nil {
			return err
		}
		return err
	})
}
Ejemplo n.º 5
0
Archivo: store.go Proyecto: andrebq/exp
func (bs *BlobStore) UpdateRefCount(k pandora.Key, delta int) error {
	var err error
	var id int64
	exists, err := bs.keyExistsInDb(&id, k)
	if !exists {
		return ErrKeyNotFound
	}
	_, err = bs.conn.Exec(`insert into pgstore_blobs_ref(id, blobid, delta) values ($1, $2, $3)`, id, k.Bytes(), delta)
	return err
}
Ejemplo n.º 6
0
Archivo: store.go Proyecto: andrebq/exp
// GetData read the contents stored under the k key
func (bs *BlobStore) GetData(out []byte, k pandora.Key) ([]byte, error) {
	var id int64
	var size int
	var err error
	exists, err := bs.keyExistsInDb(&id, k)
	if !exists {
		return nil, ErrKeyNotFound
	}
	err = bs.conn.QueryRow(`select bs.id, octet_length(bs.data) from pgstore_blobs bs where bs.blobid = $1`, k.Bytes()).Scan(&id, &size)
	if err != nil {
		return nil, err
	}
	out = sliceOfSize(out, size)
	err = bs.conn.QueryRow(`select bs.data from pgstore_blobs bs where bs.id = $1`, id).Scan(&out)
	return out, err
}