Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 137 lines (122 sloc) 3.395 kb
94e8b9c @gwenn Adds blob support.
authored
1 // Copyright 2010 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package sqlite
6
7 /*
8 #include <sqlite3.h>
9 #include <stdlib.h>
10 */
11 import "C"
12
13 import (
e8891f6 @gwenn Fix error type.
authored
14 "errors"
94e8b9c @gwenn Adds blob support.
authored
15 "unsafe"
16 )
17
b5ce230 @gwenn Add some doc.
authored
18 // Reader adapter to BLOB
94e8b9c @gwenn Adds blob support.
authored
19 type BlobReader struct {
da7e25e @gwenn Add docs for backup and blob API.
authored
20 c *Conn
21 bl *C.sqlite3_blob
22 ReadOffset int
94e8b9c @gwenn Adds blob support.
authored
23 }
24
b5ce230 @gwenn Add some doc.
authored
25 // ReadWriter adapter to BLOB
94e8b9c @gwenn Adds blob support.
authored
26 type BlobReadWriter struct {
27 BlobReader
da7e25e @gwenn Add docs for backup and blob API.
authored
28 WriteOffset int
94e8b9c @gwenn Adds blob support.
authored
29 }
30
da7e25e @gwenn Add docs for backup and blob API.
authored
31 // Zeroblobs are used to reserve space for a BLOB that is later written.
94e8b9c @gwenn Adds blob support.
authored
32 type ZeroBlobLength int
33
1d4f09b @gwenn Make possible to specify the database name in PRAGMA methods.
authored
34 // NewBlobReader opens a BLOB for incremental I/O
da7e25e @gwenn Add docs for backup and blob API.
authored
35 //
b5cfeaf @gwenn Improve doc.
authored
36 // (See http://sqlite.org/c3ref/blob_open.html)
e8891f6 @gwenn Fix error type.
authored
37 func (c *Conn) NewBlobReader(db, table, column string, row int64) (*BlobReader, error) {
94e8b9c @gwenn Adds blob support.
authored
38 bl, err := c.blob_open(db, table, column, row, false)
39 if err != nil {
40 return nil, err
41 }
da7e25e @gwenn Add docs for backup and blob API.
authored
42 return &BlobReader{c, bl, 0}, nil
94e8b9c @gwenn Adds blob support.
authored
43 }
44
1d4f09b @gwenn Make possible to specify the database name in PRAGMA methods.
authored
45 // NewBlobReadWriter open a BLOB for incremental I/O
b5cfeaf @gwenn Improve doc.
authored
46 // (See http://sqlite.org/c3ref/blob_open.html)
e8891f6 @gwenn Fix error type.
authored
47 func (c *Conn) NewBlobReadWriter(db, table, column string, row int64) (*BlobReadWriter, error) {
94e8b9c @gwenn Adds blob support.
authored
48 bl, err := c.blob_open(db, table, column, row, true)
49 if err != nil {
50 return nil, err
51 }
da7e25e @gwenn Add docs for backup and blob API.
authored
52 return &BlobReadWriter{BlobReader{c, bl, 0}, 0}, nil
94e8b9c @gwenn Adds blob support.
authored
53 }
54
e8891f6 @gwenn Fix error type.
authored
55 func (c *Conn) blob_open(db, table, column string, row int64, write bool) (*C.sqlite3_blob, error) {
94e8b9c @gwenn Adds blob support.
authored
56 zDb := C.CString(db)
57 defer C.free(unsafe.Pointer(zDb))
58 zTable := C.CString(table)
59 defer C.free(unsafe.Pointer(zTable))
60 zColumn := C.CString(column)
61 defer C.free(unsafe.Pointer(zColumn))
62 var bl *C.sqlite3_blob
63 rv := C.sqlite3_blob_open(c.db, zDb, zTable, zColumn, C.sqlite3_int64(row), btocint(write), &bl)
64 if rv != C.SQLITE_OK {
65 if bl != nil {
66 C.sqlite3_blob_close(bl)
67 }
68 return nil, c.error(rv)
69 }
70 if bl == nil {
e8891f6 @gwenn Fix error type.
authored
71 return nil, errors.New("sqlite succeeded without returning a blob")
94e8b9c @gwenn Adds blob support.
authored
72 }
73 return bl, nil
74 }
75
1d4f09b @gwenn Make possible to specify the database name in PRAGMA methods.
authored
76 // Close closes a BLOB handle
b5cfeaf @gwenn Improve doc.
authored
77 // (See http://sqlite.org/c3ref/blob_close.html)
e8891f6 @gwenn Fix error type.
authored
78 func (r *BlobReader) Close() error {
7321b68 @gwenn Test Blob misuse.
authored
79 if r == nil {
80 return errors.New("nil sqlite blob reader")
81 }
94e8b9c @gwenn Adds blob support.
authored
82 rv := C.sqlite3_blob_close(r.bl)
83 if rv != C.SQLITE_OK {
84 return r.c.error(rv)
85 }
86 r.bl = nil
87 return nil
88 }
89
1d4f09b @gwenn Make possible to specify the database name in PRAGMA methods.
authored
90 // Read reads data from a BLOB incrementally
b5cfeaf @gwenn Improve doc.
authored
91 // (See http://sqlite.org/c3ref/blob_read.html)
e8891f6 @gwenn Fix error type.
authored
92 func (r *BlobReader) Read(v []byte) (int, error) {
94e8b9c @gwenn Adds blob support.
authored
93 var p *byte
94 if len(v) > 0 {
95 p = &v[0]
96 }
da7e25e @gwenn Add docs for backup and blob API.
authored
97 rv := C.sqlite3_blob_read(r.bl, unsafe.Pointer(p), C.int(len(v)), C.int(r.ReadOffset))
94e8b9c @gwenn Adds blob support.
authored
98 if rv != C.SQLITE_OK {
99 return 0, r.c.error(rv)
100 }
da7e25e @gwenn Add docs for backup and blob API.
authored
101 r.ReadOffset += len(v)
94e8b9c @gwenn Adds blob support.
authored
102 return len(v), nil
103 }
104
1d4f09b @gwenn Make possible to specify the database name in PRAGMA methods.
authored
105 // Size returns the size of an opened BLOB
b5cfeaf @gwenn Improve doc.
authored
106 // (See http://sqlite.org/c3ref/blob_bytes.html)
e8891f6 @gwenn Fix error type.
authored
107 func (r *BlobReader) Size() (int, error) {
94e8b9c @gwenn Adds blob support.
authored
108 s := C.sqlite3_blob_bytes(r.bl)
109 return int(s), nil
110 }
111
1d4f09b @gwenn Make possible to specify the database name in PRAGMA methods.
authored
112 // Write writes data into a BLOB incrementally
b5cfeaf @gwenn Improve doc.
authored
113 // (See http://sqlite.org/c3ref/blob_write.html)
e8891f6 @gwenn Fix error type.
authored
114 func (w *BlobReadWriter) Write(v []byte) (int, error) {
94e8b9c @gwenn Adds blob support.
authored
115 var p *byte
116 if len(v) > 0 {
117 p = &v[0]
118 }
da7e25e @gwenn Add docs for backup and blob API.
authored
119 rv := C.sqlite3_blob_write(w.bl, unsafe.Pointer(p), C.int(len(v)), C.int(w.WriteOffset))
94e8b9c @gwenn Adds blob support.
authored
120 if rv != C.SQLITE_OK {
121 return 0, w.c.error(rv)
122 }
da7e25e @gwenn Add docs for backup and blob API.
authored
123 w.WriteOffset += len(v)
94e8b9c @gwenn Adds blob support.
authored
124 return len(v), nil
125 }
126
1d4f09b @gwenn Make possible to specify the database name in PRAGMA methods.
authored
127 // Reopen moves a BLOB handle to a new row
b5cfeaf @gwenn Improve doc.
authored
128 // (See http://sqlite.org/c3ref/blob_reopen.html)
e8891f6 @gwenn Fix error type.
authored
129 func (r *BlobReader) Reopen(rowid int64) error {
94e8b9c @gwenn Adds blob support.
authored
130 rv := C.sqlite3_blob_reopen(r.bl, C.sqlite3_int64(rowid))
131 if rv != C.SQLITE_OK {
132 return r.c.error(rv)
133 }
da7e25e @gwenn Add docs for backup and blob API.
authored
134 r.ReadOffset = 0
94e8b9c @gwenn Adds blob support.
authored
135 return nil
136 }
Something went wrong with that request. Please try again.