blob-ftp/server.go

176 lines
4.3 KiB
Go
Raw Permalink Normal View History

package main
import (
"database/sql"
"fmt"
"net"
"net/textproto"
_ "github.com/cznic/ql/driver"
"github.com/ncw/swift"
)
var schema []string = []string{
`CREATE TABLE IF NOT EXISTS containers (ID int, Name string, Bytes int, Count int)`,
`CREATE UNIQUE INDEX IF NOT EXISTS containersID ON containers (ID)`,
`CREATE INDEX IF NOT EXISTS containersName ON containers (Name)`,
`CREATE TABLE IF NOT EXISTS objects (ID int, Container string, Prefix string, ContentType string, LastModified time, Name string, Bytes int, Count int, SubDir string, PseudoDir bool)`,
`CREATE UNIQUE INDEX IF NOT EXISTS objectsID ON objects (ID)`,
`CREATE INDEX IF NOT EXISTS objectsName ON objects (Name)`,
`CREATE INDEX IF NOT EXISTS objectsContainer ON objects (Container)`,
}
type Conn struct {
ctrl *textproto.Conn
data net.Conn
ln net.Listener
host string
port int
mode string
sw *swift.Connection
user string
token string
path string
api string
passive bool
movesrc string
movedst string
db *sql.DB
}
func (c *Conn) Close() error {
c.db.Close()
return c.ctrl.Close()
}
func NewServer(c net.Conn) (*Conn, error) {
var err error
conn := &Conn{api: "https://api.clodo.ru", ctrl: textproto.NewConn(c), path: "/"}
conn.db, err = sql.Open("ql", "memory://mem.db")
if err != nil {
return nil, err
}
tx, err := conn.db.Begin()
if err != nil {
conn.db.Close()
return nil, err
}
for _, query := range schema {
if _, err := tx.Exec(query); err != nil {
conn.db.Close()
fmt.Printf("%s\n", err.Error())
return nil, fmt.Errorf("q: %s e: %s", query, err.Error())
}
}
if err = tx.Commit(); err != nil {
return nil, err
}
return conn, nil
}
func (c *Conn) saveContainers(cnts []swift.Container) error {
fmt.Printf("%+v\n", cnts)
tx, err := c.db.Begin()
if err != nil {
fmt.Printf("777 %s\n", err.Error())
return err
}
for _, cnt := range cnts {
if _, err = tx.Exec(`INSERT INTO containers (Name, Bytes, Count) VALUES ($1, $2, $3)`, cnt.Name, cnt.Bytes, cnt.Count); err != nil {
fmt.Printf("9999 %s\n", err.Error())
return err
}
}
if err = tx.Commit(); err != nil {
fmt.Printf("ssss %s\n", err.Error())
return err
}
return nil
}
func (c *Conn) saveObjects(cnt string, objs []swift.Object, opts *swift.ObjectsOpts) error {
fmt.Printf("%+v\n", objs)
tx, err := c.db.Begin()
if err != nil {
fmt.Printf("%s\n", err.Error())
return err
}
for _, obj := range objs {
if _, err = tx.Exec(`INSERT INTO objects (Container, Prefix, ContentType, LastModified, Name, Bytes, Count, PseudoDir, SubDir) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`, cnt, opts.Prefix, obj.ContentType, obj.LastModified, obj.Name, obj.Bytes, 1, obj.PseudoDirectory, obj.SubDir); err != nil {
fmt.Printf("aaaa %s\n", err.Error())
return err
}
}
if err = tx.Commit(); err != nil {
fmt.Printf("%s\n", err.Error())
return err
}
return nil
}
func (c *Conn) loadObjects(cnt string, opts *swift.ObjectsOpts) ([]swift.Object, error) {
var objs []swift.Object
var res swift.Object
result, err := c.db.Query(`SELECT ContentType, LastModified, Name, Bytes, PseudoDir, SubDir from objects where Container==$1 && Prefix==$2`, cnt, opts.Prefix)
if err != nil {
fmt.Printf("bbb %s\n", err.Error())
return objs, err
}
defer result.Close()
for result.Next() {
if err = result.Scan(&res.ContentType, &res.LastModified, &res.Name, &res.Bytes, &res.PseudoDirectory, &res.SubDir); err != nil {
fmt.Printf("%s\n", err.Error())
return objs, err
}
objs = append(objs, res)
}
if err := result.Err(); err != nil {
fmt.Printf("%s\n", err.Error())
return objs, err
}
if len(objs) < 1 {
return objs, fmt.Errorf("empty")
}
return objs, nil
}
func (c *Conn) loadContainers() ([]swift.Container, error) {
var cnts []swift.Container
var res swift.Container
result, err := c.db.Query(`SELECT Name, Bytes, Count from containers`)
if err != nil {
fmt.Printf("111 %s\n", err.Error())
return cnts, err
}
defer result.Close()
for result.Next() {
if err = result.Scan(&res.Name, &res.Bytes, &res.Count); err != nil {
fmt.Printf("222 %s\n", err.Error())
return cnts, err
}
cnts = append(cnts, res)
}
if err := result.Err(); err != nil {
fmt.Printf("333 %s\n", err.Error())
return cnts, err
}
if len(cnts) < 1 {
return cnts, fmt.Errorf("empty")
}
fmt.Printf("444 %+v\n", cnts)
return cnts, nil
}