1package forestdb
2
3//  Copyright (c) 2014 Couchbase, Inc.
4//  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5//  except in compliance with the License. You may obtain a copy of the License at
6//    http://www.apache.org/licenses/LICENSE-2.0
7//  Unless required by applicable law or agreed to in writing, software distributed under the
8//  License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
9//  either express or implied. See the License for the specific language governing permissions
10//  and limitations under the License.
11
12//#include <libforestdb/forestdb.h>
13import "C"
14
15import (
16	"unsafe"
17)
18
19type SeqNum uint64
20
21// ForestDB doc structure definition
22type Doc struct {
23	doc *C.fdb_doc
24}
25
26// NewDoc creates a new FDB_DOC instance on heap with a given key, its metadata, and its doc body
27func NewDoc(key, meta, body []byte) (*Doc, error) {
28	var k, m, b unsafe.Pointer
29
30	if len(key) != 0 {
31		k = unsafe.Pointer(&key[0])
32	}
33
34	if len(meta) != 0 {
35		m = unsafe.Pointer(&meta[0])
36	}
37
38	if len(body) != 0 {
39		b = unsafe.Pointer(&body[0])
40	}
41
42	lenk := len(key)
43	lenm := len(meta)
44	lenb := len(body)
45
46	rv := Doc{}
47
48	Log.Tracef("fdb_doc_create call k:%p doc:%v m:%v b:%v", k, rv.doc, m, b)
49	errNo := C.fdb_doc_create(&rv.doc,
50		k, C.size_t(lenk), m, C.size_t(lenm), b, C.size_t(lenb))
51	Log.Tracef("fdb_doc_create ret k:%p errNo:%v doc:%v", k, errNo, rv.doc)
52	if errNo != RESULT_SUCCESS {
53		return nil, Error(errNo)
54	}
55	return &rv, nil
56}
57
58// Update a FDB_DOC instance with a given metadata and body
59// NOTE: does not update the database, just the in memory structure
60func (d *Doc) Update(meta, body []byte) error {
61	var m, b unsafe.Pointer
62
63	if len(meta) != 0 {
64		m = unsafe.Pointer(&meta[0])
65	}
66
67	if len(body) != 0 {
68		b = unsafe.Pointer(&body[0])
69	}
70
71	lenm := len(meta)
72	lenb := len(body)
73	Log.Tracef("fdb_doc_update call d:%p doc:%v m:%v b:%v", d, d.doc, m, b)
74	errNo := C.fdb_doc_update(&d.doc, m, C.size_t(lenm), b, C.size_t(lenb))
75	Log.Tracef("fdb_doc_update retn d:%p errNo:%v doc:%v m:%v b:%v", d, errNo, d.doc, m, b)
76	if errNo != RESULT_SUCCESS {
77		return Error(errNo)
78	}
79	return nil
80}
81
82// Key returns the document key
83func (d *Doc) Key() []byte {
84	return C.GoBytes(d.doc.key, C.int(d.doc.keylen))
85}
86
87// Meta returns the document metadata
88func (d *Doc) Meta() []byte {
89	return C.GoBytes(d.doc.meta, C.int(d.doc.metalen))
90}
91
92// Body returns the document body
93func (d *Doc) Body() []byte {
94	return C.GoBytes(d.doc.body, C.int(d.doc.bodylen))
95}
96
97// SeqNum returns the document sequence number
98func (d *Doc) SeqNum() SeqNum {
99	return SeqNum(d.doc.seqnum)
100}
101
102// SetSeqNum sets the document sequence number
103// NOTE: only to be used when initiating a sequence number lookup
104func (d *Doc) SetSeqNum(sn SeqNum) {
105	C.fdb_doc_set_seqnum(d.doc, C.fdb_seqnum_t(sn))
106}
107
108// Offset returns the offset position on disk
109func (d *Doc) Offset() uint64 {
110	return uint64(d.doc.offset)
111}
112
113// Deleted returns whether or not this document has been deleted
114func (d *Doc) Deleted() bool {
115	return bool(d.doc.deleted)
116}
117
118// Close releases resources allocated to this document
119func (d *Doc) Close() error {
120	Log.Tracef("fdb_doc_free call d:%p doc:%v", d, d.doc)
121	errNo := C.fdb_doc_free(d.doc)
122	Log.Tracef("fdb_doc_free retn d:%p errNo:%v", d, errNo)
123	if errNo != RESULT_SUCCESS {
124		return Error(errNo)
125	}
126	return nil
127}
128