1 package pgx
2
3 import (
4 "context"
5 "errors"
6 "io"
7 )
8
9
10
11
12
13 type LargeObjects struct {
14 tx Tx
15 }
16
17 type LargeObjectMode int32
18
19 const (
20 LargeObjectModeWrite LargeObjectMode = 0x20000
21 LargeObjectModeRead LargeObjectMode = 0x40000
22 )
23
24
25 func (o *LargeObjects) Create(ctx context.Context, oid uint32) (uint32, error) {
26 err := o.tx.QueryRow(ctx, "select lo_create($1)", oid).Scan(&oid)
27 return oid, err
28 }
29
30
31
32 func (o *LargeObjects) Open(ctx context.Context, oid uint32, mode LargeObjectMode) (*LargeObject, error) {
33 var fd int32
34 err := o.tx.QueryRow(ctx, "select lo_open($1, $2)", oid, mode).Scan(&fd)
35 if err != nil {
36 return nil, err
37 }
38 return &LargeObject{fd: fd, tx: o.tx, ctx: ctx}, nil
39 }
40
41
42 func (o *LargeObjects) Unlink(ctx context.Context, oid uint32) error {
43 var result int32
44 err := o.tx.QueryRow(ctx, "select lo_unlink($1)", oid).Scan(&result)
45 if err != nil {
46 return err
47 }
48
49 if result != 1 {
50 return errors.New("failed to remove large object")
51 }
52
53 return nil
54 }
55
56
57
58
59
60
61
62
63 type LargeObject struct {
64 ctx context.Context
65 tx Tx
66 fd int32
67 }
68
69
70 func (o *LargeObject) Write(p []byte) (int, error) {
71 var n int
72 err := o.tx.QueryRow(o.ctx, "select lowrite($1, $2)", o.fd, p).Scan(&n)
73 if err != nil {
74 return n, err
75 }
76
77 if n < 0 {
78 return 0, errors.New("failed to write to large object")
79 }
80
81 return n, nil
82 }
83
84
85 func (o *LargeObject) Read(p []byte) (int, error) {
86 var res []byte
87 err := o.tx.QueryRow(o.ctx, "select loread($1, $2)", o.fd, len(p)).Scan(&res)
88 copy(p, res)
89 if err != nil {
90 return len(res), err
91 }
92
93 if len(res) < len(p) {
94 err = io.EOF
95 }
96 return len(res), err
97 }
98
99
100 func (o *LargeObject) Seek(offset int64, whence int) (n int64, err error) {
101 err = o.tx.QueryRow(o.ctx, "select lo_lseek64($1, $2, $3)", o.fd, offset, whence).Scan(&n)
102 return n, err
103 }
104
105
106 func (o *LargeObject) Tell() (n int64, err error) {
107 err = o.tx.QueryRow(o.ctx, "select lo_tell64($1)", o.fd).Scan(&n)
108 return n, err
109 }
110
111
112 func (o *LargeObject) Truncate(size int64) (err error) {
113 _, err = o.tx.Exec(o.ctx, "select lo_truncate64($1, $2)", o.fd, size)
114 return err
115 }
116
117
118 func (o *LargeObject) Close() error {
119 _, err := o.tx.Exec(o.ctx, "select lo_close($1)", o.fd)
120 return err
121 }
122
View as plain text