1
0
Fork 0

Covert dumps to queries in HTTP service

There is no need for special logic at the Store level.
master
Philip O Toole 8 years ago
parent e6586f41f2
commit 5ed6ef0ae8

@ -8,7 +8,6 @@ import (
"encoding/json" "encoding/json"
"expvar" "expvar"
"fmt" "fmt"
"io"
"io/ioutil" "io/ioutil"
"log" "log"
"net" "net"
@ -54,9 +53,6 @@ type Store interface {
// Backup returns a byte slice representing a backup of the node state. // Backup returns a byte slice representing a backup of the node state.
Backup(leader bool) ([]byte, error) Backup(leader bool) ([]byte, error)
// Load loads a SQLite .dump state from a reader
Load(r io.Reader) (int, error)
} }
// CredentialStore is the interface credential stores must support. // CredentialStore is the interface credential stores must support.
@ -382,7 +378,18 @@ func (s *Service) handleLoad(w http.ResponseWriter, r *http.Request) {
return return
} }
n, err := s.store.Load(r.Body) timings, err := timings(r)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
b, err := ioutil.ReadAll(r.Body)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
n, err := s.store.Execute([]string{string(b)}, timings, false)
if err != nil { if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
return return

@ -2,7 +2,6 @@ package http
import ( import (
"fmt" "fmt"
"io"
"net/http" "net/http"
"testing" "testing"
@ -393,10 +392,6 @@ func (m *MockStore) Backup(leader bool) ([]byte, error) {
return nil, nil return nil, nil
} }
func (m *MockStore) Load(r io.Reader) (int, error) {
return 0, nil
}
type mockCredentialStore struct { type mockCredentialStore struct {
CheckOK bool CheckOK bool
HasPermOK bool HasPermOK bool

@ -450,25 +450,6 @@ func (s *Store) Execute(queries []string, timings, tx bool) ([]*sql.Result, erro
return r.results, r.error return r.results, r.error
} }
// Load loads a SQLite .dump state from a reader.
func (s *Store) Load(r io.Reader) (int, error) {
if s.raft.State() != raft.Leader {
return 0, ErrNotLeader
}
b, err := ioutil.ReadAll(r)
if err != nil {
return 0, err
}
_, err = s.Execute([]string{string(b)}, false, false)
if err != nil {
return 0, err
}
return 0, nil
}
// Backup return a snapshot of the underlying database. // Backup return a snapshot of the underlying database.
// //
// If leader is true, this operation is performed with a read consistency // If leader is true, this operation is performed with a read consistency

@ -1,7 +1,6 @@
package store package store
import ( import (
"bytes"
"encoding/json" "encoding/json"
"io/ioutil" "io/ioutil"
"net" "net"
@ -222,13 +221,9 @@ CREATE TABLE foo (id integer not null primary key, name text);
INSERT INTO "foo" VALUES(1,'fiona'); INSERT INTO "foo" VALUES(1,'fiona');
COMMIT; COMMIT;
` `
buf := bytes.NewBufferString(dump) _, err := s.Execute([]string{dump}, false, false)
n, err := s.Load(buf)
if err != nil { if err != nil {
t.Fatalf("failed to load dump: %s", err.Error()) t.Fatalf("failed to load simple dump: %s", err.Error())
}
if n != 5 {
t.Fatal("wrong number of statements loaded")
} }
// Check that data were loaded correctly. // Check that data were loaded correctly.
@ -244,7 +239,7 @@ COMMIT;
} }
} }
func Test_SingleNodeTrigger(t *testing.T) { func Test_SingleNodeSingleCommandTrigger(t *testing.T) {
s := mustNewStore(true) s := mustNewStore(true)
defer os.RemoveAll(s.Path()) defer os.RemoveAll(s.Path())
@ -268,13 +263,9 @@ CREATE VIEW foobar as select name as Person, Age as age from foo inner join bar
CREATE TRIGGER new_foobar instead of insert on foobar begin insert into foo (name) values (new.Person); insert into bar (nameid, age) values ((select id from foo where name == new.Person), new.Age); end; CREATE TRIGGER new_foobar instead of insert on foobar begin insert into foo (name) values (new.Person); insert into bar (nameid, age) values ((select id from foo where name == new.Person), new.Age); end;
COMMIT; COMMIT;
` `
buf := bytes.NewBufferString(dump) _, err := s.Execute([]string{dump}, false, false)
n, err := s.Load(buf)
if err != nil { if err != nil {
t.Fatalf("failed to load dump: %s", err.Error()) t.Fatalf("failed to load dump with trigger: %s", err.Error())
}
if n == 5 {
t.Fatal("wrong number of statements loaded")
} }
// Check that the VIEW and TRIGGER are OK by using both. // Check that the VIEW and TRIGGER are OK by using both.
@ -301,13 +292,9 @@ func Test_SingleNodeLoadNoStatements(t *testing.T) {
BEGIN TRANSACTION; BEGIN TRANSACTION;
COMMIT; COMMIT;
` `
buf := bytes.NewBufferString(dump) _, err := s.Execute([]string{dump}, false, false)
n, err := s.Load(buf)
if err != nil { if err != nil {
t.Fatalf("failed to load dump: %s", err.Error()) t.Fatalf("failed to load dump with no commands: %s", err.Error())
}
if n != 3 {
t.Fatal("wrong number of statements loaded, exp: 1, got: ", n)
} }
} }
@ -321,13 +308,10 @@ func Test_SingleNodeLoadEmpty(t *testing.T) {
defer s.Close(true) defer s.Close(true)
s.WaitForLeader(10 * time.Second) s.WaitForLeader(10 * time.Second)
buf := bytes.NewBufferString("") dump := ``
n, err := s.Load(buf) _, err := s.Execute([]string{dump}, false, false)
if err != nil { if err != nil {
t.Fatalf("failed to load dump: %s", err.Error()) t.Fatalf("failed to load empty dump: %s", err.Error())
}
if n != 0 {
t.Fatal("wrong number of statements loaded")
} }
} }
@ -341,10 +325,9 @@ func Test_SingleNodeLoadChinook(t *testing.T) {
defer s.Close(true) defer s.Close(true)
s.WaitForLeader(10 * time.Second) s.WaitForLeader(10 * time.Second)
buf := bytes.NewBufferString(chinook.DB) _, err := s.Execute([]string{chinook.DB}, false, false)
_, err := s.Load(buf)
if err != nil { if err != nil {
t.Fatalf("failed to load dump: %s", err.Error()) t.Fatalf("failed to load chinook dump: %s", err.Error())
} }
// Check that data were loaded correctly. // Check that data were loaded correctly.

Loading…
Cancel
Save