Skip to content
This repository was archived by the owner on Jan 24, 2020. It is now read-only.

Commit 6dee06c

Browse files
committed
Initial Commit
Based on Go-MySQL-Driver
0 parents  commit 6dee06c

14 files changed

+2368
-0
lines changed

LICENSE

+373
Large diffs are not rendered by default.

buffer.go

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// Copyright 2013 Julien Schmidt. All rights reserved.
2+
// http://www.julienschmidt.com
3+
//
4+
// This Source Code Form is subject to the terms of the Mozilla Public
5+
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
6+
// You can obtain one at http://mozilla.org/MPL/2.0/.
7+
8+
package sphinxql
9+
10+
import (
11+
"io"
12+
)
13+
14+
const (
15+
defaultBufSize = 4096
16+
)
17+
18+
type buffer struct {
19+
buf []byte
20+
rd io.Reader
21+
idx int
22+
length int
23+
}
24+
25+
func newBuffer(rd io.Reader) *buffer {
26+
return &buffer{
27+
buf: make([]byte, defaultBufSize),
28+
rd: rd,
29+
}
30+
}
31+
32+
// fill reads at least _need_ bytes in the buffer
33+
// existing data in the buffer gets lost
34+
func (b *buffer) fill(need int) (err error) {
35+
b.idx = 0
36+
b.length = 0
37+
38+
n := 0
39+
for b.length < need {
40+
n, err = b.rd.Read(b.buf[b.length:])
41+
b.length += n
42+
43+
if err == nil {
44+
continue
45+
}
46+
return // err
47+
}
48+
49+
return
50+
}
51+
52+
// read len(p) bytes
53+
func (b *buffer) read(p []byte) (err error) {
54+
need := len(p)
55+
56+
if b.length < need {
57+
if b.length > 0 {
58+
copy(p[0:b.length], b.buf[b.idx:])
59+
need -= b.length
60+
p = p[b.length:]
61+
62+
b.idx = 0
63+
b.length = 0
64+
}
65+
66+
if need >= len(b.buf) {
67+
var n int
68+
has := 0
69+
for err == nil && need > has {
70+
n, err = b.rd.Read(p[has:])
71+
has += n
72+
}
73+
return
74+
}
75+
76+
err = b.fill(need) // err deferred
77+
}
78+
79+
copy(p, b.buf[b.idx:])
80+
b.idx += need
81+
b.length -= need
82+
return
83+
}

connection.go

+160
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
// Copyright 2013 Julien Schmidt. All rights reserved.
2+
// http://www.julienschmidt.com
3+
//
4+
// This Source Code Form is subject to the terms of the Mozilla Public
5+
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
6+
// You can obtain one at http://mozilla.org/MPL/2.0/.
7+
8+
package sphinxql
9+
10+
import (
11+
"database/sql/driver"
12+
"errors"
13+
"net"
14+
"strings"
15+
)
16+
17+
type sphinxqlConn struct {
18+
cfg *config
19+
flags ClientFlag
20+
charset byte
21+
cipher []byte
22+
netConn net.Conn
23+
buf *buffer
24+
protocol uint8
25+
sequence uint8
26+
affectedRows uint64
27+
insertId uint64
28+
}
29+
30+
type config struct {
31+
user string
32+
passwd string
33+
net string
34+
addr string
35+
dbname string
36+
params map[string]string
37+
}
38+
39+
// Handles parameters set in DSN
40+
func (mc *sphinxqlConn) handleParams() (err error) {
41+
for param, val := range mc.cfg.params {
42+
switch param {
43+
// Charset
44+
case "charset":
45+
charsets := strings.Split(val, ",")
46+
for _, charset := range charsets {
47+
err = mc.exec("SET NAMES " + charset)
48+
if err != nil {
49+
return
50+
}
51+
}
52+
53+
// Timeout - already handled on connecting
54+
case "timeout":
55+
continue
56+
57+
// System Vars
58+
default:
59+
err = mc.exec("SET " + param + "=" + val + "")
60+
if err != nil {
61+
return
62+
}
63+
}
64+
}
65+
66+
return
67+
}
68+
69+
func (mc *sphinxqlConn) Begin() (driver.Tx, error) {
70+
err := mc.exec("START TRANSACTION")
71+
if err == nil {
72+
return &sphinxqlTx{mc}, err
73+
}
74+
75+
return nil, err
76+
}
77+
78+
func (mc *sphinxqlConn) Close() (err error) {
79+
mc.writeCommandPacket(COM_QUIT)
80+
mc.cfg = nil
81+
mc.buf = nil
82+
mc.netConn.Close()
83+
mc.netConn = nil
84+
return
85+
}
86+
87+
func (mc *sphinxqlConn) Prepare(query string) (driver.Stmt, error) {
88+
return &sphinxqlStmt{
89+
mc: mc,
90+
query: query,
91+
}, nil
92+
}
93+
94+
func (mc *sphinxqlConn) Exec(query string, args []driver.Value) (_ driver.Result, err error) {
95+
if len(args) == 0 {
96+
mc.affectedRows = 0
97+
mc.insertId = 0
98+
99+
err = mc.exec(query)
100+
if err == nil {
101+
return &sphinxqlResult{
102+
affectedRows: int64(mc.affectedRows),
103+
insertId: int64(mc.insertId),
104+
}, err
105+
} else {
106+
return nil, err
107+
}
108+
109+
}
110+
return nil, errors.New("args not supported")
111+
112+
}
113+
114+
// Internal function to execute commands
115+
func (mc *sphinxqlConn) exec(query string) (err error) {
116+
// Send command
117+
err = mc.writeCommandPacketStr(COM_QUERY, query)
118+
if err != nil {
119+
return
120+
}
121+
122+
// Read Result
123+
var resLen int
124+
resLen, err = mc.readResultSetHeaderPacket()
125+
if err == nil && resLen > 0 {
126+
err = mc.readUntilEOF()
127+
if err != nil {
128+
return
129+
}
130+
131+
err = mc.readUntilEOF()
132+
}
133+
134+
return
135+
}
136+
137+
func (mc *sphinxqlConn) Query(query string, args []driver.Value) (_ driver.Rows, err error) {
138+
if len(args) == 0 {
139+
var rows *sphinxqlRows
140+
// Send command
141+
err = mc.writeCommandPacketStr(COM_QUERY, query)
142+
if err == nil {
143+
// Read Result
144+
var resLen int
145+
resLen, err = mc.readResultSetHeaderPacket()
146+
if err == nil {
147+
rows = &sphinxqlRows{mc, nil, false}
148+
149+
if resLen > 0 {
150+
// Columns
151+
rows.columns, err = mc.readColumns(resLen)
152+
}
153+
return rows, err
154+
}
155+
}
156+
return nil, err
157+
}
158+
159+
return nil, errors.New("args not supported")
160+
}

const.go

+126
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
// Copyright 2013 Julien Schmidt. All rights reserved.
2+
// http://www.julienschmidt.com
3+
//
4+
// This Source Code Form is subject to the terms of the Mozilla Public
5+
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
6+
// You can obtain one at http://mozilla.org/MPL/2.0/.
7+
8+
package sphinxql
9+
10+
const (
11+
MIN_PROTOCOL_VERSION byte = 10
12+
//MAX_PACKET_SIZE = 1<<24 - 1
13+
TIME_FORMAT = "2006-01-02 15:04:05"
14+
)
15+
16+
// MySQL constants documentation:
17+
// http://dev.mysql.com/doc/internals/en/client-server-protocol.html
18+
19+
type ClientFlag uint32
20+
21+
const (
22+
CLIENT_LONG_PASSWORD ClientFlag = 1 << iota
23+
CLIENT_FOUND_ROWS
24+
CLIENT_LONG_FLAG
25+
CLIENT_CONNECT_WITH_DB
26+
CLIENT_NO_SCHEMA
27+
CLIENT_COMPRESS
28+
CLIENT_ODBC
29+
CLIENT_LOCAL_FILES
30+
CLIENT_IGNORE_SPACE
31+
CLIENT_PROTOCOL_41
32+
CLIENT_INTERACTIVE
33+
CLIENT_SSL
34+
CLIENT_IGNORE_SIGPIPE
35+
CLIENT_TRANSACTIONS
36+
CLIENT_RESERVED
37+
CLIENT_SECURE_CONN
38+
CLIENT_MULTI_STATEMENTS
39+
CLIENT_MULTI_RESULTS
40+
)
41+
42+
type commandType byte
43+
44+
const (
45+
COM_QUIT commandType = iota + 1
46+
COM_INIT_DB
47+
COM_QUERY
48+
COM_FIELD_LIST
49+
COM_CREATE_DB
50+
COM_DROP_DB
51+
COM_REFRESH
52+
COM_SHUTDOWN
53+
COM_STATISTICS
54+
COM_PROCESS_INFO
55+
COM_CONNECT
56+
COM_PROCESS_KILL
57+
COM_DEBUG
58+
COM_PING
59+
COM_TIME
60+
COM_DELAYED_INSERT
61+
COM_CHANGE_USER
62+
COM_BINLOG_DUMP
63+
COM_TABLE_DUMP
64+
COM_CONNECT_OUT
65+
COM_REGISTER_SLAVE
66+
COM_STMT_PREPARE
67+
COM_STMT_EXECUTE
68+
COM_STMT_SEND_LONG_DATA
69+
COM_STMT_CLOSE
70+
COM_STMT_RESET
71+
COM_SET_OPTION
72+
COM_STMT_FETCH
73+
)
74+
75+
const (
76+
FIELD_TYPE_DECIMAL byte = iota
77+
FIELD_TYPE_TINY
78+
FIELD_TYPE_SHORT
79+
FIELD_TYPE_LONG
80+
FIELD_TYPE_FLOAT
81+
FIELD_TYPE_DOUBLE
82+
FIELD_TYPE_NULL
83+
FIELD_TYPE_TIMESTAMP
84+
FIELD_TYPE_LONGLONG
85+
FIELD_TYPE_INT24
86+
FIELD_TYPE_DATE
87+
FIELD_TYPE_TIME
88+
FIELD_TYPE_DATETIME
89+
FIELD_TYPE_YEAR
90+
FIELD_TYPE_NEWDATE
91+
FIELD_TYPE_VARCHAR
92+
FIELD_TYPE_BIT
93+
)
94+
const (
95+
FIELD_TYPE_NEWDECIMAL byte = iota + 0xf6
96+
FIELD_TYPE_ENUM
97+
FIELD_TYPE_SET
98+
FIELD_TYPE_TINY_BLOB
99+
FIELD_TYPE_MEDIUM_BLOB
100+
FIELD_TYPE_LONG_BLOB
101+
FIELD_TYPE_BLOB
102+
FIELD_TYPE_VAR_STRING
103+
FIELD_TYPE_STRING
104+
FIELD_TYPE_GEOMETRY
105+
)
106+
107+
type FieldFlag uint16
108+
109+
const (
110+
FLAG_NOT_NULL FieldFlag = 1 << iota
111+
FLAG_PRI_KEY
112+
FLAG_UNIQUE_KEY
113+
FLAG_MULTIPLE_KEY
114+
FLAG_BLOB
115+
FLAG_UNSIGNED
116+
FLAG_ZEROFILL
117+
FLAG_BINARY
118+
FLAG_ENUM
119+
FLAG_AUTO_INCREMENT
120+
FLAG_TIMESTAMP
121+
FLAG_SET
122+
FLAG_UNKNOWN_1
123+
FLAG_UNKNOWN_2
124+
FLAG_UNKNOWN_3
125+
FLAG_UNKNOWN_4
126+
)

0 commit comments

Comments
 (0)