2015-04-14 03:14:38 +03:00
package main
import (
2015-05-07 14:52:59 +03:00
"database/sql"
"fmt"
2015-04-14 03:14:38 +03:00
"net"
"net/textproto"
2015-04-14 18:43:09 +03:00
2015-05-07 14:52:59 +03:00
_ "github.com/cznic/ql/driver"
2015-04-14 18:43:09 +03:00
"github.com/ncw/swift"
2015-04-14 03:14:38 +03:00
)
2015-05-07 14:52:59 +03:00
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) ` ,
` 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) ` ,
}
2015-04-14 03:14:38 +03:00
type Conn struct {
2015-04-15 14:57:47 +03:00
ctrl * textproto . Conn
2015-04-30 16:54:17 +03:00
data net . Conn
2015-04-15 14:57:47 +03:00
ln net . Listener
host string
port int
mode string
sw * swift . Connection
user string
token string
path string
api string
passive bool
2015-05-06 16:15:39 +03:00
movesrc string
movedst string
2015-05-07 14:52:59 +03:00
db * sql . DB
2015-04-14 03:14:38 +03:00
}
func ( c * Conn ) Close ( ) error {
2015-05-07 14:52:59 +03:00
c . db . Close ( )
2015-04-14 03:14:38 +03:00
return c . ctrl . Close ( )
}
func NewServer ( c net . Conn ) ( * Conn , error ) {
2015-05-07 14:52:59 +03:00
var err error
conn := & Conn { api : "https://api.clodo.ru" , user : "storage_21_1" , token : "56652e9028ded5ea5d4772ba80e578ce" , 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) VALUES ($1, $2, $3, $4, $5, $6, $7) ` , cnt , opts . Prefix , obj . ContentType , obj . LastModified , obj . Name , obj . Bytes , 1 ) ; 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 from objects where Container==$1 && Prefix==$1 ` , 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 ) ; 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
2015-04-14 03:14:38 +03:00
}