mirror of
https://github.com/dnote/dnote
synced 2026-03-14 22:45:50 +01:00
Find command (#149)
* Implement basic full text search * Avoid lag in log while making network calls * Allow to restrict search by book name
This commit is contained in:
parent
fa1da50fc5
commit
14b0cf623f
31 changed files with 1181 additions and 338 deletions
|
|
@ -1,7 +1,7 @@
|
|||
language: go
|
||||
|
||||
go:
|
||||
- 1.9.x
|
||||
- 1.11.x
|
||||
|
||||
install:
|
||||
- curl -L https://github.com/golang/dep/releases/download/v0.3.2/dep-linux-amd64 -o ./dep && chmod +x ./dep
|
||||
|
|
|
|||
6
Gopkg.lock
generated
6
Gopkg.lock
generated
|
|
@ -58,12 +58,12 @@
|
|||
version = "v0.0.4"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:bc03901fc8f0965ccba8bc453eae21a9b04f95999eab664c7de6dc7290f4e8f4"
|
||||
digest = "1:8bbdb2b3dce59271877770d6fe7dcbb8362438fa7d2e1e1f688e4bf2aac72706"
|
||||
name = "github.com/mattn/go-sqlite3"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "25ecb14adfc7543176f7d85291ec7dba82c6f7e4"
|
||||
version = "v1.9.0"
|
||||
revision = "c7c4067b79cc51e6dfdcef5c702e74b1e0fa7c75"
|
||||
version = "v1.10.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:7365acd48986e205ccb8652cc746f09c8b7876030d53710ea6ef7d0bd0dcd7ca"
|
||||
|
|
|
|||
|
|
@ -47,4 +47,4 @@
|
|||
|
||||
[[constraint]]
|
||||
name = "github.com/mattn/go-sqlite3"
|
||||
version = "1.9.0"
|
||||
version = "1.10.0"
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ type SyncFragNote struct {
|
|||
UpdatedAt time.Time `json:"updated_at"`
|
||||
AddedOn int64 `json:"added_on"`
|
||||
EditedOn int64 `json:"edited_on"`
|
||||
Content string `json:"content"`
|
||||
Body string `json:"content"`
|
||||
Public bool `json:"public"`
|
||||
Deleted bool `json:"deleted"`
|
||||
}
|
||||
|
|
@ -252,7 +252,7 @@ func DeleteBook(ctx infra.DnoteCtx, apiKey, uuid string) (DeleteBookResp, error)
|
|||
// CreateNotePayload is a payload for creating a note
|
||||
type CreateNotePayload struct {
|
||||
BookUUID string `json:"book_uuid"`
|
||||
Content string `json:"content"`
|
||||
Body string `json:"content"`
|
||||
}
|
||||
|
||||
// CreateNoteResp is the response from create note endpoint
|
||||
|
|
@ -274,7 +274,7 @@ type RespNote struct {
|
|||
UUID string `json:"uuid"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
Content string `json:"content"`
|
||||
Body string `json:"content"`
|
||||
AddedOn int64 `json:"added_on"`
|
||||
Public bool `json:"public"`
|
||||
USN int `json:"usn"`
|
||||
|
|
@ -286,7 +286,7 @@ type RespNote struct {
|
|||
func CreateNote(ctx infra.DnoteCtx, apiKey, bookUUID, content string) (CreateNoteResp, error) {
|
||||
payload := CreateNotePayload{
|
||||
BookUUID: bookUUID,
|
||||
Content: content,
|
||||
Body: content,
|
||||
}
|
||||
b, err := json.Marshal(payload)
|
||||
if err != nil {
|
||||
|
|
@ -316,7 +316,7 @@ func CreateNote(ctx infra.DnoteCtx, apiKey, bookUUID, content string) (CreateNot
|
|||
|
||||
type updateNotePayload struct {
|
||||
BookUUID *string `json:"book_uuid"`
|
||||
Content *string `json:"content"`
|
||||
Body *string `json:"content"`
|
||||
Public *bool `json:"public"`
|
||||
}
|
||||
|
||||
|
|
@ -330,7 +330,7 @@ type UpdateNoteResp struct {
|
|||
func UpdateNote(ctx infra.DnoteCtx, apiKey, uuid, bookUUID, content string, public bool) (UpdateNoteResp, error) {
|
||||
payload := updateNotePayload{
|
||||
BookUUID: &bookUUID,
|
||||
Content: &content,
|
||||
Body: &content,
|
||||
Public: &public,
|
||||
}
|
||||
b, err := json.Marshal(payload)
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ func preRun(cmd *cobra.Command, args []string) error {
|
|||
// NewCmd returns a new add command
|
||||
func NewCmd(ctx infra.DnoteCtx) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "add <content>",
|
||||
Use: "add <book>",
|
||||
Short: "Add a note",
|
||||
Aliases: []string{"a", "n", "new"},
|
||||
Example: example,
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ func NewRun(ctx infra.DnoteCtx) core.RunEFunc {
|
|||
return func(cmd *cobra.Command, args []string) error {
|
||||
db := ctx.DB
|
||||
bookLabel := args[0]
|
||||
noteID := args[1]
|
||||
noteRowID := args[1]
|
||||
|
||||
var bookUUID string
|
||||
err := db.QueryRow("SELECT uuid FROM books WHERE label = ?", bookLabel).Scan(&bookUUID)
|
||||
|
|
@ -69,13 +69,13 @@ func NewRun(ctx infra.DnoteCtx) core.RunEFunc {
|
|||
}
|
||||
|
||||
var info noteInfo
|
||||
err = db.QueryRow(`SELECT books.label, notes.uuid, notes.content, notes.added_on, notes.edited_on
|
||||
err = db.QueryRow(`SELECT books.label, notes.uuid, notes.body, notes.added_on, notes.edited_on
|
||||
FROM notes
|
||||
INNER JOIN books ON books.uuid = notes.book_uuid
|
||||
WHERE notes.id = ? AND books.uuid = ?`, noteID, bookUUID).
|
||||
WHERE notes.rowid = ? AND books.uuid = ?`, noteRowID, bookUUID).
|
||||
Scan(&info.BookLabel, &info.UUID, &info.Content, &info.AddedOn, &info.EditedOn)
|
||||
if err == sql.ErrNoRows {
|
||||
return errors.Errorf("note %s not found in the book '%s'", noteID, bookLabel)
|
||||
return errors.Errorf("note %s not found in the book '%s'", noteRowID, bookLabel)
|
||||
} else if err != nil {
|
||||
return errors.Wrap(err, "querying the note")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ func newRun(ctx infra.DnoteCtx) core.RunEFunc {
|
|||
return func(cmd *cobra.Command, args []string) error {
|
||||
db := ctx.DB
|
||||
bookLabel := args[0]
|
||||
noteID := args[1]
|
||||
noteRowID := args[1]
|
||||
|
||||
bookUUID, err := core.GetBookUUID(ctx, bookLabel)
|
||||
if err != nil {
|
||||
|
|
@ -59,9 +59,9 @@ func newRun(ctx infra.DnoteCtx) core.RunEFunc {
|
|||
}
|
||||
|
||||
var noteUUID, oldContent string
|
||||
err = db.QueryRow("SELECT uuid, content FROM notes WHERE id = ? AND book_uuid = ?", noteID, bookUUID).Scan(¬eUUID, &oldContent)
|
||||
err = db.QueryRow("SELECT uuid, body FROM notes WHERE rowid = ? AND book_uuid = ?", noteRowID, bookUUID).Scan(¬eUUID, &oldContent)
|
||||
if err == sql.ErrNoRows {
|
||||
return errors.Errorf("note %s not found in the book '%s'", noteID, bookLabel)
|
||||
return errors.Errorf("note %s not found in the book '%s'", noteRowID, bookLabel)
|
||||
} else if err != nil {
|
||||
return errors.Wrap(err, "querying the book")
|
||||
}
|
||||
|
|
@ -93,8 +93,8 @@ func newRun(ctx infra.DnoteCtx) core.RunEFunc {
|
|||
}
|
||||
|
||||
_, err = tx.Exec(`UPDATE notes
|
||||
SET content = ?, edited_on = ?, dirty = ?
|
||||
WHERE id = ? AND book_uuid = ?`, newContent, ts, true, noteID, bookUUID)
|
||||
SET body = ?, edited_on = ?, dirty = ?
|
||||
WHERE rowid = ? AND book_uuid = ?`, newContent, ts, true, noteRowID, bookUUID)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return errors.Wrap(err, "updating the note")
|
||||
|
|
|
|||
180
cmd/find/find.go
Normal file
180
cmd/find/find.go
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
package find
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/dnote/cli/core"
|
||||
"github.com/dnote/cli/infra"
|
||||
"github.com/dnote/cli/log"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var example = `
|
||||
# find notes by a keyword
|
||||
dnote find rpoplpush
|
||||
|
||||
# find notes by multiple keywords
|
||||
dnote find "building a heap"
|
||||
|
||||
# find notes within a book
|
||||
dnote find "merge sort" -b algorithm
|
||||
`
|
||||
|
||||
var bookName string
|
||||
|
||||
func preRun(cmd *cobra.Command, args []string) error {
|
||||
if len(args) != 1 {
|
||||
return errors.New("Incorrect number of argument")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewCmd returns a new remove command
|
||||
func NewCmd(ctx infra.DnoteCtx) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "find",
|
||||
Short: "Find notes by keywords",
|
||||
Aliases: []string{"f"},
|
||||
Example: example,
|
||||
PreRunE: preRun,
|
||||
RunE: newRun(ctx),
|
||||
}
|
||||
|
||||
f := cmd.Flags()
|
||||
f.StringVarP(&bookName, "book", "b", "", "book name to find notes in")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
// noteInfo is an information about the note to be printed on screen
|
||||
type noteInfo struct {
|
||||
RowID int
|
||||
BookLabel string
|
||||
Body string
|
||||
}
|
||||
|
||||
// formatFTSSnippet turns the matched snippet from a full text search
|
||||
// into a format suitable for CLI output
|
||||
func formatFTSSnippet(s string) (string, error) {
|
||||
// first, strip all new lines
|
||||
body := newLineReg.ReplaceAllString(s, " ")
|
||||
|
||||
var format, buf strings.Builder
|
||||
var args []interface{}
|
||||
|
||||
toks := tokenize(body)
|
||||
|
||||
for _, tok := range toks {
|
||||
if tok.Kind == tokenKindHLBegin || tok.Kind == tokenKindEOL {
|
||||
format.WriteString("%s")
|
||||
args = append(args, buf.String())
|
||||
|
||||
buf.Reset()
|
||||
} else if tok.Kind == tokenKindHLEnd {
|
||||
format.WriteString("%s")
|
||||
str := log.SprintfYellow("%s", buf.String())
|
||||
args = append(args, str)
|
||||
|
||||
buf.Reset()
|
||||
} else {
|
||||
if err := buf.WriteByte(tok.Value); err != nil {
|
||||
return "", errors.Wrap(err, "building string")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Sprintf(format.String(), args...), nil
|
||||
}
|
||||
|
||||
// escapePhrase escapes the user-supplied FTS keywords by wrapping each term around
|
||||
// double quotations so that they are treated as 'strings' as defined by SQLite FTS5.
|
||||
func escapePhrase(s string) (string, error) {
|
||||
var b strings.Builder
|
||||
|
||||
terms := strings.Fields(s)
|
||||
|
||||
for idx, term := range terms {
|
||||
if _, err := b.WriteString(fmt.Sprintf("\"%s\"", term)); err != nil {
|
||||
return "", errors.Wrap(err, "writing string to builder")
|
||||
}
|
||||
|
||||
if idx != len(term)-1 {
|
||||
if err := b.WriteByte(' '); err != nil {
|
||||
return "", errors.Wrap(err, "writing space to builder")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return b.String(), nil
|
||||
}
|
||||
|
||||
func doQuery(ctx infra.DnoteCtx, query, bookName string) (*sql.Rows, error) {
|
||||
db := ctx.DB
|
||||
|
||||
sql := `SELECT
|
||||
notes.rowid,
|
||||
books.label AS book_label,
|
||||
snippet(note_fts, 0, '<dnotehl>', '</dnotehl>', '...', 28)
|
||||
FROM note_fts
|
||||
INNER JOIN notes ON notes.rowid = note_fts.rowid
|
||||
INNER JOIN books ON notes.book_uuid = books.uuid
|
||||
WHERE note_fts MATCH ?`
|
||||
args := []interface{}{query}
|
||||
|
||||
if bookName != "" {
|
||||
sql = fmt.Sprintf("%s AND books.label = ?", sql)
|
||||
args = append(args, bookName)
|
||||
}
|
||||
|
||||
rows, err := db.Query(sql, args...)
|
||||
|
||||
return rows, err
|
||||
}
|
||||
|
||||
func newRun(ctx infra.DnoteCtx) core.RunEFunc {
|
||||
return func(cmd *cobra.Command, args []string) error {
|
||||
phrase, err := escapePhrase(args[0])
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "escaping phrase")
|
||||
}
|
||||
|
||||
rows, err := doQuery(ctx, phrase, bookName)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "querying notes")
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
infos := []noteInfo{}
|
||||
for rows.Next() {
|
||||
var info noteInfo
|
||||
|
||||
var body string
|
||||
err = rows.Scan(&info.RowID, &info.BookLabel, &body)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "scanning a row")
|
||||
}
|
||||
|
||||
body, err := formatFTSSnippet(body)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "formatting a body")
|
||||
}
|
||||
|
||||
info.Body = body
|
||||
|
||||
infos = append(infos, info)
|
||||
}
|
||||
|
||||
for _, info := range infos {
|
||||
bookLabel := log.SprintfYellow("(%s)", info.BookLabel)
|
||||
rowid := log.SprintfYellow("(%d)", info.RowID)
|
||||
|
||||
log.Plainf("%s %s %s\n", bookLabel, rowid, info.Body)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
82
cmd/find/lexer.go
Normal file
82
cmd/find/lexer.go
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
package find
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
)
|
||||
|
||||
var newLineReg = regexp.MustCompile(`\r?\n`)
|
||||
|
||||
const (
|
||||
// tokenKindChar represents utf-8 character
|
||||
tokenKindChar = iota
|
||||
// tokenKindHLBegin represents a beginning of a highlighted section
|
||||
tokenKindHLBegin
|
||||
// tokenKindHLEnd represents an end of a highlighted section
|
||||
tokenKindHLEnd
|
||||
// tokenKindEOL represents an end of line
|
||||
tokenKindEOL
|
||||
)
|
||||
|
||||
type token struct {
|
||||
Value byte
|
||||
Kind int
|
||||
}
|
||||
|
||||
// getNextIdx validates that the given index is within the range of the given string.
|
||||
// If so, it returns the given index. Otherwise it returns -1.
|
||||
func getNextIdx(candidate int, s string) int {
|
||||
if candidate <= len(s)-1 {
|
||||
return candidate
|
||||
}
|
||||
|
||||
return -1
|
||||
}
|
||||
|
||||
// scanToken scans the given string for a token at the given index. It returns
|
||||
// a token and the next index to look for a token. If the given string is exhausted,
|
||||
// the next index will be -1.
|
||||
func scanToken(idx int, s string) (token, int) {
|
||||
if s[idx] == '<' {
|
||||
if len(s)-idx >= 9 {
|
||||
lookahead := 9
|
||||
candidate := s[idx : idx+lookahead]
|
||||
|
||||
if candidate == "<dnotehl>" {
|
||||
nextIdx := getNextIdx(idx+lookahead, s)
|
||||
return token{Kind: tokenKindHLBegin}, nextIdx
|
||||
}
|
||||
}
|
||||
|
||||
if len(s)-idx >= 10 {
|
||||
lookahead := 10
|
||||
candidate := s[idx : idx+lookahead]
|
||||
|
||||
if candidate == "</dnotehl>" {
|
||||
nextIdx := getNextIdx(idx+lookahead, s)
|
||||
return token{Kind: tokenKindHLEnd}, nextIdx
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nextIdx := getNextIdx(idx+1, s)
|
||||
|
||||
return token{Value: s[idx], Kind: tokenKindChar}, nextIdx
|
||||
}
|
||||
|
||||
// tokenize lexically analyzes the given matched snippet from a full text search
|
||||
// and builds a slice of tokens
|
||||
func tokenize(s string) []token {
|
||||
var ret []token
|
||||
|
||||
idx := 0
|
||||
for idx != -1 {
|
||||
var tok token
|
||||
tok, idx = scanToken(idx, s)
|
||||
|
||||
ret = append(ret, tok)
|
||||
}
|
||||
|
||||
ret = append(ret, token{Kind: tokenKindEOL})
|
||||
|
||||
return ret
|
||||
}
|
||||
213
cmd/find/lexer_test.go
Normal file
213
cmd/find/lexer_test.go
Normal file
|
|
@ -0,0 +1,213 @@
|
|||
package find
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/dnote/cli/testutils"
|
||||
)
|
||||
|
||||
func TestScanToken(t *testing.T) {
|
||||
testCases := []struct {
|
||||
input string
|
||||
idx int
|
||||
retTok token
|
||||
retIdx int
|
||||
}{
|
||||
{
|
||||
input: "foo bar",
|
||||
idx: 1,
|
||||
retTok: token{Value: 'o', Kind: tokenKindChar},
|
||||
retIdx: 2,
|
||||
},
|
||||
{
|
||||
input: "foo bar",
|
||||
idx: 6,
|
||||
retTok: token{Value: 'r', Kind: tokenKindChar},
|
||||
retIdx: -1,
|
||||
},
|
||||
{
|
||||
input: "foo <bar>",
|
||||
idx: 4,
|
||||
retTok: token{Value: '<', Kind: tokenKindChar},
|
||||
retIdx: 5,
|
||||
},
|
||||
{
|
||||
input: "foo <dnotehL>",
|
||||
idx: 4,
|
||||
retTok: token{Value: '<', Kind: tokenKindChar},
|
||||
retIdx: 5,
|
||||
},
|
||||
{
|
||||
input: "foo <dnotehl>bar</dnotehl> foo bar",
|
||||
idx: 4,
|
||||
retTok: token{Kind: tokenKindHLBegin},
|
||||
retIdx: 13,
|
||||
},
|
||||
{
|
||||
input: "foo <dnotehl>bar</dnotehl> <dnotehl>foo</dnotehl> bar",
|
||||
idx: 4,
|
||||
retTok: token{Kind: tokenKindHLBegin},
|
||||
retIdx: 13,
|
||||
},
|
||||
{
|
||||
input: "foo <dnotehl>bar</dnotehl> <dnotehl>foo</dnotehl> bar",
|
||||
idx: 27,
|
||||
retTok: token{Kind: tokenKindHLBegin},
|
||||
retIdx: 36,
|
||||
},
|
||||
{
|
||||
input: "foo <dnotehl>bar</dnotehl> foo bar",
|
||||
idx: 13,
|
||||
retTok: token{Value: 'b', Kind: tokenKindChar},
|
||||
retIdx: 14,
|
||||
},
|
||||
{
|
||||
input: "foo <dnotehl>bar</dnotehl> foo bar",
|
||||
idx: 16,
|
||||
retTok: token{Kind: tokenKindHLEnd},
|
||||
retIdx: 26,
|
||||
},
|
||||
{
|
||||
input: "<dno<dnotehl>tehl>",
|
||||
idx: 0,
|
||||
retTok: token{Value: '<', Kind: tokenKindChar},
|
||||
retIdx: 1,
|
||||
},
|
||||
{
|
||||
input: "<dno<dnotehl>tehl>",
|
||||
idx: 4,
|
||||
retTok: token{Kind: tokenKindHLBegin},
|
||||
retIdx: 13,
|
||||
},
|
||||
{
|
||||
input: "foo <dnotehl>bar</dnotehl>",
|
||||
idx: 16,
|
||||
retTok: token{Kind: tokenKindHLEnd},
|
||||
retIdx: -1,
|
||||
},
|
||||
// user writes reserved token
|
||||
{
|
||||
input: "foo <dnotehl>",
|
||||
idx: 4,
|
||||
retTok: token{Kind: tokenKindHLBegin},
|
||||
retIdx: -1,
|
||||
},
|
||||
}
|
||||
|
||||
for tcIdx, tc := range testCases {
|
||||
t.Run(fmt.Sprintf("test case %d", tcIdx), func(t *testing.T) {
|
||||
tok, nextIdx := scanToken(tc.idx, tc.input)
|
||||
|
||||
testutils.AssertEqual(t, nextIdx, tc.retIdx, "retIdx mismatch")
|
||||
testutils.AssertDeepEqual(t, tok, tc.retTok, "retTok mismatch")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestTokenize(t *testing.T) {
|
||||
testCases := []struct {
|
||||
input string
|
||||
tokens []token
|
||||
}{
|
||||
{
|
||||
input: "ab<dnotehl>c</dnotehl>",
|
||||
tokens: []token{
|
||||
token{
|
||||
Kind: tokenKindChar,
|
||||
Value: 'a',
|
||||
},
|
||||
token{
|
||||
Kind: tokenKindChar,
|
||||
Value: 'b',
|
||||
},
|
||||
token{
|
||||
Kind: tokenKindHLBegin,
|
||||
},
|
||||
token{
|
||||
Kind: tokenKindChar,
|
||||
Value: 'c',
|
||||
},
|
||||
token{
|
||||
Kind: tokenKindHLEnd,
|
||||
},
|
||||
token{
|
||||
Kind: tokenKindEOL,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
input: "ab<dnotehl>c</dnotehl>d",
|
||||
tokens: []token{
|
||||
token{
|
||||
Kind: tokenKindChar,
|
||||
Value: 'a',
|
||||
},
|
||||
token{
|
||||
Kind: tokenKindChar,
|
||||
Value: 'b',
|
||||
},
|
||||
token{
|
||||
Kind: tokenKindHLBegin,
|
||||
},
|
||||
token{
|
||||
Kind: tokenKindChar,
|
||||
Value: 'c',
|
||||
},
|
||||
token{
|
||||
Kind: tokenKindHLEnd,
|
||||
},
|
||||
token{
|
||||
Kind: tokenKindChar,
|
||||
Value: 'd',
|
||||
},
|
||||
token{
|
||||
Kind: tokenKindEOL,
|
||||
},
|
||||
},
|
||||
},
|
||||
// user writes a reserved token
|
||||
{
|
||||
input: "<dnotehl><dnotehl></dnotehl>",
|
||||
tokens: []token{
|
||||
token{
|
||||
Kind: tokenKindHLBegin,
|
||||
},
|
||||
token{
|
||||
Kind: tokenKindHLBegin,
|
||||
},
|
||||
token{
|
||||
Kind: tokenKindHLEnd,
|
||||
},
|
||||
token{
|
||||
Kind: tokenKindEOL,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
input: "<dnotehl></dnotehl></dnotehl>",
|
||||
tokens: []token{
|
||||
token{
|
||||
Kind: tokenKindHLBegin,
|
||||
},
|
||||
token{
|
||||
Kind: tokenKindHLEnd,
|
||||
},
|
||||
token{
|
||||
Kind: tokenKindHLEnd,
|
||||
},
|
||||
token{
|
||||
Kind: tokenKindEOL,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for tcIdx, tc := range testCases {
|
||||
t.Run(fmt.Sprintf("test case %d", tcIdx), func(t *testing.T) {
|
||||
tokens := tokenize(tc.input)
|
||||
|
||||
testutils.AssertDeepEqual(t, tokens, tc.tokens, "tokens mismatch")
|
||||
})
|
||||
}
|
||||
}
|
||||
29
cmd/ls/ls.go
29
cmd/ls/ls.go
|
|
@ -20,7 +20,7 @@ var example = `
|
|||
dnote ls javascript
|
||||
`
|
||||
|
||||
var deprecationWarning = `and "view" will replace it in v0.5.0.
|
||||
var deprecationWarning = `and "view" will replace it in v1.0.0.
|
||||
|
||||
Run "dnote view --help" for more information.
|
||||
`
|
||||
|
|
@ -48,6 +48,7 @@ func NewCmd(ctx infra.DnoteCtx) *cobra.Command {
|
|||
return cmd
|
||||
}
|
||||
|
||||
// NewRun returns a new run function for ls
|
||||
func NewRun(ctx infra.DnoteCtx) core.RunEFunc {
|
||||
return func(cmd *cobra.Command, args []string) error {
|
||||
if len(args) == 0 {
|
||||
|
|
@ -75,8 +76,8 @@ type bookInfo struct {
|
|||
|
||||
// noteInfo is an information about the note to be printed on screen
|
||||
type noteInfo struct {
|
||||
ID int
|
||||
Content string
|
||||
RowID int
|
||||
Body string
|
||||
}
|
||||
|
||||
// getNewlineIdx returns the index of newline character in a string
|
||||
|
|
@ -92,18 +93,18 @@ func getNewlineIdx(str string) int {
|
|||
return ret
|
||||
}
|
||||
|
||||
// formatContent returns an excerpt of the given raw note content and a boolean
|
||||
// formatBody returns an excerpt of the given raw note content and a boolean
|
||||
// indicating if the returned string has been excertped
|
||||
func formatContent(noteContent string) (string, bool) {
|
||||
newlineIdx := getNewlineIdx(noteContent)
|
||||
func formatBody(noteBody string) (string, bool) {
|
||||
newlineIdx := getNewlineIdx(noteBody)
|
||||
|
||||
if newlineIdx > -1 {
|
||||
ret := strings.Trim(noteContent[0:newlineIdx], " ")
|
||||
ret := strings.Trim(noteBody[0:newlineIdx], " ")
|
||||
|
||||
return ret, true
|
||||
}
|
||||
|
||||
return strings.Trim(noteContent, " "), false
|
||||
return strings.Trim(noteBody, " "), false
|
||||
}
|
||||
|
||||
func printBooks(ctx infra.DnoteCtx) error {
|
||||
|
|
@ -148,7 +149,7 @@ func printNotes(ctx infra.DnoteCtx, bookName string) error {
|
|||
return errors.Wrap(err, "querying the book")
|
||||
}
|
||||
|
||||
rows, err := db.Query(`SELECT id, content FROM notes WHERE book_uuid = ? ORDER BY added_on ASC;`, bookUUID)
|
||||
rows, err := db.Query(`SELECT rowid, body FROM notes WHERE book_uuid = ? ORDER BY added_on ASC;`, bookUUID)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "querying notes")
|
||||
}
|
||||
|
|
@ -157,7 +158,7 @@ func printNotes(ctx infra.DnoteCtx, bookName string) error {
|
|||
infos := []noteInfo{}
|
||||
for rows.Next() {
|
||||
var info noteInfo
|
||||
err = rows.Scan(&info.ID, &info.Content)
|
||||
err = rows.Scan(&info.RowID, &info.Body)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "scanning a row")
|
||||
}
|
||||
|
|
@ -168,14 +169,14 @@ func printNotes(ctx infra.DnoteCtx, bookName string) error {
|
|||
log.Infof("on book %s\n", bookName)
|
||||
|
||||
for _, info := range infos {
|
||||
content, isExcerpt := formatContent(info.Content)
|
||||
body, isExcerpt := formatBody(info.Body)
|
||||
|
||||
index := log.SprintfYellow("(%d)", info.ID)
|
||||
rowid := log.SprintfYellow("(%d)", info.RowID)
|
||||
if isExcerpt {
|
||||
content = fmt.Sprintf("%s %s", content, log.SprintfYellow("[---More---]"))
|
||||
body = fmt.Sprintf("%s %s", body, log.SprintfYellow("[---More---]"))
|
||||
}
|
||||
|
||||
log.Plainf("%s %s\n", index, content)
|
||||
log.Plainf("%s %s\n", rowid, body)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -52,9 +52,9 @@ func newRun(ctx infra.DnoteCtx) core.RunEFunc {
|
|||
}
|
||||
|
||||
targetBook := args[0]
|
||||
noteID := args[1]
|
||||
noteRowID := args[1]
|
||||
|
||||
if err := removeNote(ctx, noteID, targetBook); err != nil {
|
||||
if err := removeNote(ctx, noteRowID, targetBook); err != nil {
|
||||
return errors.Wrap(err, "removing the note")
|
||||
}
|
||||
|
||||
|
|
@ -62,7 +62,7 @@ func newRun(ctx infra.DnoteCtx) core.RunEFunc {
|
|||
}
|
||||
}
|
||||
|
||||
func removeNote(ctx infra.DnoteCtx, noteID, bookLabel string) error {
|
||||
func removeNote(ctx infra.DnoteCtx, noteRowID, bookLabel string) error {
|
||||
db := ctx.DB
|
||||
|
||||
bookUUID, err := core.GetBookUUID(ctx, bookLabel)
|
||||
|
|
@ -71,15 +71,15 @@ func removeNote(ctx infra.DnoteCtx, noteID, bookLabel string) error {
|
|||
}
|
||||
|
||||
var noteUUID, noteContent string
|
||||
err = db.QueryRow("SELECT uuid, content FROM notes WHERE id = ? AND book_uuid = ?", noteID, bookUUID).Scan(¬eUUID, ¬eContent)
|
||||
err = db.QueryRow("SELECT uuid, body FROM notes WHERE rowid = ? AND book_uuid = ?", noteRowID, bookUUID).Scan(¬eUUID, ¬eContent)
|
||||
if err == sql.ErrNoRows {
|
||||
return errors.Errorf("note %s not found in the book '%s'", noteID, bookLabel)
|
||||
return errors.Errorf("note %s not found in the book '%s'", noteRowID, bookLabel)
|
||||
} else if err != nil {
|
||||
return errors.Wrap(err, "querying the book")
|
||||
}
|
||||
|
||||
// todo: multiline
|
||||
log.Printf("content: \"%s\"\n", noteContent)
|
||||
log.Printf("body: \"%s\"\n", noteContent)
|
||||
|
||||
ok, err := utils.AskConfirmation("remove this note?", false)
|
||||
if err != nil {
|
||||
|
|
@ -95,7 +95,7 @@ func removeNote(ctx infra.DnoteCtx, noteID, bookLabel string) error {
|
|||
return errors.Wrap(err, "beginning a transaction")
|
||||
}
|
||||
|
||||
if _, err = tx.Exec("UPDATE notes SET deleted = ?, dirty = ?, content = ? WHERE uuid = ? AND book_uuid = ?", true, true, "", noteUUID, bookUUID); err != nil {
|
||||
if _, err = tx.Exec("UPDATE notes SET deleted = ?, dirty = ?, body = ? WHERE uuid = ? AND book_uuid = ?", true, true, "", noteUUID, bookUUID); err != nil {
|
||||
return errors.Wrap(err, "removing the note")
|
||||
}
|
||||
tx.Commit()
|
||||
|
|
@ -127,7 +127,7 @@ func removeBook(ctx infra.DnoteCtx, bookLabel string) error {
|
|||
return errors.Wrap(err, "beginning a transaction")
|
||||
}
|
||||
|
||||
if _, err = tx.Exec("UPDATE notes SET deleted = ?, dirty = ?, content = ? WHERE book_uuid = ?", true, true, "", bookUUID); err != nil {
|
||||
if _, err = tx.Exec("UPDATE notes SET deleted = ?, dirty = ?, body = ? WHERE book_uuid = ?", true, true, "", bookUUID); err != nil {
|
||||
return errors.Wrap(err, "removing notes in the book")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -252,8 +252,8 @@ func mergeNote(tx *sql.Tx, serverNote client.SyncFragNote, localNote core.Note)
|
|||
|
||||
// if the local copy is deleted, and the it was edited on the server, override with server values and mark it not dirty.
|
||||
if localNote.Deleted {
|
||||
if _, err := tx.Exec("UPDATE notes SET usn = ?, book_uuid = ?, content = ?, edited_on = ?, deleted = ?, public = ?, dirty = ? WHERE uuid = ?",
|
||||
serverNote.USN, serverNote.BookUUID, serverNote.Content, serverNote.EditedOn, serverNote.Deleted, serverNote.Public, false, serverNote.UUID); err != nil {
|
||||
if _, err := tx.Exec("UPDATE notes SET usn = ?, book_uuid = ?, body = ?, edited_on = ?, deleted = ?, public = ?, dirty = ? WHERE uuid = ?",
|
||||
serverNote.USN, serverNote.BookUUID, serverNote.Body, serverNote.EditedOn, serverNote.Deleted, serverNote.Public, false, serverNote.UUID); err != nil {
|
||||
return errors.Wrapf(err, "updating local note %s", serverNote.UUID)
|
||||
}
|
||||
|
||||
|
|
@ -261,8 +261,8 @@ func mergeNote(tx *sql.Tx, serverNote client.SyncFragNote, localNote core.Note)
|
|||
}
|
||||
|
||||
// TODO: if the client copy is dirty, perform field-by-field merge and report conflict instead of overwriting
|
||||
if _, err := tx.Exec("UPDATE notes SET usn = ?, book_uuid = ?, content = ?, edited_on = ?, deleted = ?, public = ? WHERE uuid = ?",
|
||||
serverNote.USN, serverNote.BookUUID, serverNote.Content, serverNote.EditedOn, serverNote.Deleted, serverNote.Public, serverNote.UUID); err != nil {
|
||||
if _, err := tx.Exec("UPDATE notes SET usn = ?, book_uuid = ?, body = ?, edited_on = ?, deleted = ?, public = ? WHERE uuid = ?",
|
||||
serverNote.USN, serverNote.BookUUID, serverNote.Body, serverNote.EditedOn, serverNote.Deleted, serverNote.Public, serverNote.UUID); err != nil {
|
||||
return errors.Wrapf(err, "updating local note %s", serverNote.UUID)
|
||||
}
|
||||
|
||||
|
|
@ -279,7 +279,7 @@ func stepSyncNote(tx *sql.Tx, n client.SyncFragNote) error {
|
|||
|
||||
// if note exists in the server and does not exist in the client, insert the note.
|
||||
if err == sql.ErrNoRows {
|
||||
note := core.NewNote(n.UUID, n.BookUUID, n.Content, n.AddedOn, n.EditedOn, n.USN, n.Public, n.Deleted, false)
|
||||
note := core.NewNote(n.UUID, n.BookUUID, n.Body, n.AddedOn, n.EditedOn, n.USN, n.Public, n.Deleted, false)
|
||||
|
||||
if err := note.Insert(tx); err != nil {
|
||||
return errors.Wrapf(err, "inserting note with uuid %s", n.UUID)
|
||||
|
|
@ -303,7 +303,7 @@ func fullSyncNote(tx *sql.Tx, n client.SyncFragNote) error {
|
|||
|
||||
// if note exists in the server and does not exist in the client, insert the note.
|
||||
if err == sql.ErrNoRows {
|
||||
note := core.NewNote(n.UUID, n.BookUUID, n.Content, n.AddedOn, n.EditedOn, n.USN, n.Public, n.Deleted, false)
|
||||
note := core.NewNote(n.UUID, n.BookUUID, n.Body, n.AddedOn, n.EditedOn, n.USN, n.Public, n.Deleted, false)
|
||||
|
||||
if err := note.Insert(tx); err != nil {
|
||||
return errors.Wrapf(err, "inserting note with uuid %s", n.UUID)
|
||||
|
|
@ -506,13 +506,14 @@ func cleanLocalBooks(tx *sql.Tx, fullList *syncList) error {
|
|||
|
||||
func fullSync(ctx infra.DnoteCtx, tx *sql.Tx, apiKey string) error {
|
||||
log.Debug("performing a full sync\n")
|
||||
log.Info("resolving delta.")
|
||||
|
||||
list, err := getSyncList(ctx, apiKey, 0)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "getting sync list")
|
||||
}
|
||||
|
||||
log.Infof("resolving delta (total %d).", list.getLength())
|
||||
fmt.Printf(" (total %d).", list.getLength())
|
||||
|
||||
// clean resources that are in erroneous states
|
||||
if err := cleanLocalNotes(tx, &list); err != nil {
|
||||
|
|
@ -557,12 +558,14 @@ func fullSync(ctx infra.DnoteCtx, tx *sql.Tx, apiKey string) error {
|
|||
func stepSync(ctx infra.DnoteCtx, tx *sql.Tx, apiKey string, afterUSN int) error {
|
||||
log.Debug("performing a step sync\n")
|
||||
|
||||
log.Info("resolving delta.")
|
||||
|
||||
list, err := getSyncList(ctx, apiKey, afterUSN)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "getting sync list")
|
||||
}
|
||||
|
||||
log.Infof("resolving delta (total %d).", list.getLength())
|
||||
fmt.Printf(" (total %d).", list.getLength())
|
||||
|
||||
for _, note := range list.Notes {
|
||||
if err := stepSyncNote(tx, note); err != nil {
|
||||
|
|
@ -703,7 +706,7 @@ func sendBooks(ctx infra.DnoteCtx, tx *sql.Tx, apiKey string) (bool, error) {
|
|||
func sendNotes(ctx infra.DnoteCtx, tx *sql.Tx, apiKey string) (bool, error) {
|
||||
isBehind := false
|
||||
|
||||
rows, err := tx.Query("SELECT uuid, book_uuid, content, public, deleted, usn FROM notes WHERE dirty")
|
||||
rows, err := tx.Query("SELECT uuid, book_uuid, body, public, deleted, usn FROM notes WHERE dirty")
|
||||
if err != nil {
|
||||
return isBehind, errors.Wrap(err, "getting syncable notes")
|
||||
}
|
||||
|
|
@ -712,7 +715,7 @@ func sendNotes(ctx infra.DnoteCtx, tx *sql.Tx, apiKey string) (bool, error) {
|
|||
for rows.Next() {
|
||||
var note core.Note
|
||||
|
||||
if err = rows.Scan(¬e.UUID, ¬e.BookUUID, ¬e.Content, ¬e.Public, ¬e.Deleted, ¬e.USN); err != nil {
|
||||
if err = rows.Scan(¬e.UUID, ¬e.BookUUID, ¬e.Body, ¬e.Public, ¬e.Deleted, ¬e.USN); err != nil {
|
||||
return isBehind, errors.Wrap(err, "scanning a syncable note")
|
||||
}
|
||||
|
||||
|
|
@ -731,7 +734,7 @@ func sendNotes(ctx infra.DnoteCtx, tx *sql.Tx, apiKey string) (bool, error) {
|
|||
|
||||
continue
|
||||
} else {
|
||||
resp, err := client.CreateNote(ctx, apiKey, note.BookUUID, note.Content)
|
||||
resp, err := client.CreateNote(ctx, apiKey, note.BookUUID, note.Body)
|
||||
if err != nil {
|
||||
return isBehind, errors.Wrap(err, "creating a note")
|
||||
}
|
||||
|
|
@ -764,7 +767,7 @@ func sendNotes(ctx infra.DnoteCtx, tx *sql.Tx, apiKey string) (bool, error) {
|
|||
|
||||
respUSN = resp.Result.USN
|
||||
} else {
|
||||
resp, err := client.UpdateNote(ctx, apiKey, note.UUID, note.BookUUID, note.Content, note.Public)
|
||||
resp, err := client.UpdateNote(ctx, apiKey, note.UUID, note.BookUUID, note.Body, note.Public)
|
||||
if err != nil {
|
||||
return isBehind, errors.Wrap(err, "updating a note")
|
||||
}
|
||||
|
|
@ -801,10 +804,12 @@ func sendNotes(ctx infra.DnoteCtx, tx *sql.Tx, apiKey string) (bool, error) {
|
|||
}
|
||||
|
||||
func sendChanges(ctx infra.DnoteCtx, tx *sql.Tx, apiKey string) (bool, error) {
|
||||
log.Info("sending changes.")
|
||||
|
||||
var delta int
|
||||
err := tx.QueryRow("SELECT (SELECT count(*) FROM notes WHERE dirty) + (SELECT count(*) FROM books WHERE dirty)").Scan(&delta)
|
||||
|
||||
log.Infof("sending changes (total %d).", delta)
|
||||
fmt.Printf(" (total %d).", delta)
|
||||
|
||||
behind1, err := sendBooks(ctx, tx, apiKey)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -157,17 +157,17 @@ func TestSyncDeleteNote(t *testing.T) {
|
|||
db := ctx.DB
|
||||
|
||||
testutils.MustExec(t, "inserting b1 for test case %d", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "b1-label")
|
||||
testutils.MustExec(t, "inserting n1 for test case %d", db, "INSERT INTO notes (uuid, book_uuid, usn, content, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", b1UUID, 10, "n1 content", 1541108743, false, true)
|
||||
testutils.MustExec(t, "inserting n2 for test case %d", db, "INSERT INTO notes (uuid, book_uuid, usn, content, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n2-uuid", b1UUID, 11, "n2 content", 1541108743, false, true)
|
||||
testutils.MustExec(t, "inserting n1 for test case %d", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", b1UUID, 10, "n1 body", 1541108743, false, true)
|
||||
testutils.MustExec(t, "inserting n2 for test case %d", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n2-uuid", b1UUID, 11, "n2 body", 1541108743, false, true)
|
||||
|
||||
var n1 core.Note
|
||||
testutils.MustScan(t, "getting n1 for test case",
|
||||
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, content, public, deleted, dirty FROM notes WHERE uuid = ?", "n1-uuid"),
|
||||
&n1.UUID, &n1.BookUUID, &n1.USN, &n1.AddedOn, &n1.EditedOn, &n1.Content, &n1.Public, &n1.Deleted, &n1.Dirty)
|
||||
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, body, public, deleted, dirty FROM notes WHERE uuid = ?", "n1-uuid"),
|
||||
&n1.UUID, &n1.BookUUID, &n1.USN, &n1.AddedOn, &n1.EditedOn, &n1.Body, &n1.Public, &n1.Deleted, &n1.Dirty)
|
||||
var n2 core.Note
|
||||
testutils.MustScan(t, "getting n2 for test case",
|
||||
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, content, public, deleted, dirty FROM notes WHERE uuid = ?", "n2-uuid"),
|
||||
&n2.UUID, &n2.BookUUID, &n2.USN, &n2.AddedOn, &n2.EditedOn, &n2.Content, &n2.Public, &n2.Deleted, &n2.Dirty)
|
||||
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, body, public, deleted, dirty FROM notes WHERE uuid = ?", "n2-uuid"),
|
||||
&n2.UUID, &n2.BookUUID, &n2.USN, &n2.AddedOn, &n2.EditedOn, &n2.Body, &n2.Public, &n2.Deleted, &n2.Dirty)
|
||||
|
||||
// execute
|
||||
tx, err := db.Begin()
|
||||
|
|
@ -193,19 +193,19 @@ func TestSyncDeleteNote(t *testing.T) {
|
|||
|
||||
var n1Record core.Note
|
||||
testutils.MustScan(t, "getting n1 for test case",
|
||||
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, content, public, deleted, dirty FROM notes WHERE uuid = ?", n1.UUID),
|
||||
&n1Record.UUID, &n1Record.BookUUID, &n1Record.USN, &n1Record.AddedOn, &n1Record.EditedOn, &n1Record.Content, &n1Record.Public, &n1Record.Deleted, &n1Record.Dirty)
|
||||
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, body, public, deleted, dirty FROM notes WHERE uuid = ?", n1.UUID),
|
||||
&n1Record.UUID, &n1Record.BookUUID, &n1Record.USN, &n1Record.AddedOn, &n1Record.EditedOn, &n1Record.Body, &n1Record.Public, &n1Record.Deleted, &n1Record.Dirty)
|
||||
var n2Record core.Note
|
||||
testutils.MustScan(t, "getting n2 for test case",
|
||||
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, content, public, deleted, dirty FROM notes WHERE uuid = ?", n2.UUID),
|
||||
&n2Record.UUID, &n2Record.BookUUID, &n2Record.USN, &n2Record.AddedOn, &n2Record.EditedOn, &n2Record.Content, &n2Record.Public, &n2Record.Deleted, &n2Record.Dirty)
|
||||
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, body, public, deleted, dirty FROM notes WHERE uuid = ?", n2.UUID),
|
||||
&n2Record.UUID, &n2Record.BookUUID, &n2Record.USN, &n2Record.AddedOn, &n2Record.EditedOn, &n2Record.Body, &n2Record.Public, &n2Record.Deleted, &n2Record.Dirty)
|
||||
|
||||
testutils.AssertEqual(t, n1Record.UUID, n1.UUID, "n1 UUID mismatch for test case")
|
||||
testutils.AssertEqual(t, n1Record.BookUUID, n1.BookUUID, "n1 BookUUID mismatch for test case")
|
||||
testutils.AssertEqual(t, n1Record.USN, n1.USN, "n1 USN mismatch for test case")
|
||||
testutils.AssertEqual(t, n1Record.AddedOn, n1.AddedOn, "n1 AddedOn mismatch for test case")
|
||||
testutils.AssertEqual(t, n1Record.EditedOn, n1.EditedOn, "n1 EditedOn mismatch for test case")
|
||||
testutils.AssertEqual(t, n1Record.Content, n1.Content, "n1 Content mismatch for test case")
|
||||
testutils.AssertEqual(t, n1Record.Body, n1.Body, "n1 Body mismatch for test case")
|
||||
testutils.AssertEqual(t, n1Record.Public, n1.Public, "n1 Public mismatch for test case")
|
||||
testutils.AssertEqual(t, n1Record.Deleted, n1.Deleted, "n1 Deleted mismatch for test case")
|
||||
testutils.AssertEqual(t, n1Record.Dirty, n1.Dirty, "n1 Dirty mismatch for test case")
|
||||
|
|
@ -215,7 +215,7 @@ func TestSyncDeleteNote(t *testing.T) {
|
|||
testutils.AssertEqual(t, n2Record.USN, n2.USN, "n2 USN mismatch for test case")
|
||||
testutils.AssertEqual(t, n2Record.AddedOn, n2.AddedOn, "n2 AddedOn mismatch for test case")
|
||||
testutils.AssertEqual(t, n2Record.EditedOn, n2.EditedOn, "n2 EditedOn mismatch for test case")
|
||||
testutils.AssertEqual(t, n2Record.Content, n2.Content, "n2 Content mismatch for test case")
|
||||
testutils.AssertEqual(t, n2Record.Body, n2.Body, "n2 Body mismatch for test case")
|
||||
testutils.AssertEqual(t, n2Record.Public, n2.Public, "n2 Public mismatch for test case")
|
||||
testutils.AssertEqual(t, n2Record.Deleted, n2.Deleted, "n2 Deleted mismatch for test case")
|
||||
testutils.AssertEqual(t, n2Record.Dirty, n2.Dirty, "n2 Dirty mismatch for test case")
|
||||
|
|
@ -231,17 +231,17 @@ func TestSyncDeleteNote(t *testing.T) {
|
|||
db := ctx.DB
|
||||
|
||||
testutils.MustExec(t, "inserting b1 for test case %d", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "b1-label")
|
||||
testutils.MustExec(t, "inserting n1 for test case %d", db, "INSERT INTO notes (uuid, book_uuid, usn, content, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", b1UUID, 10, "n1 content", 1541108743, false, false)
|
||||
testutils.MustExec(t, "inserting n2 for test case %d", db, "INSERT INTO notes (uuid, book_uuid, usn, content, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n2-uuid", b1UUID, 11, "n2 content", 1541108743, false, false)
|
||||
testutils.MustExec(t, "inserting n1 for test case %d", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", b1UUID, 10, "n1 body", 1541108743, false, false)
|
||||
testutils.MustExec(t, "inserting n2 for test case %d", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n2-uuid", b1UUID, 11, "n2 body", 1541108743, false, false)
|
||||
|
||||
var n1 core.Note
|
||||
testutils.MustScan(t, "getting n1 for test case",
|
||||
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, content, public, deleted, dirty FROM notes WHERE uuid = ?", "n1-uuid"),
|
||||
&n1.UUID, &n1.BookUUID, &n1.USN, &n1.AddedOn, &n1.EditedOn, &n1.Content, &n1.Public, &n1.Deleted, &n1.Dirty)
|
||||
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, body, public, deleted, dirty FROM notes WHERE uuid = ?", "n1-uuid"),
|
||||
&n1.UUID, &n1.BookUUID, &n1.USN, &n1.AddedOn, &n1.EditedOn, &n1.Body, &n1.Public, &n1.Deleted, &n1.Dirty)
|
||||
var n2 core.Note
|
||||
testutils.MustScan(t, "getting n2 for test case",
|
||||
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, content, public, deleted, dirty FROM notes WHERE uuid = ?", "n2-uuid"),
|
||||
&n2.UUID, &n2.BookUUID, &n2.USN, &n2.AddedOn, &n2.EditedOn, &n2.Content, &n2.Public, &n2.Deleted, &n2.Dirty)
|
||||
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, body, public, deleted, dirty FROM notes WHERE uuid = ?", "n2-uuid"),
|
||||
&n2.UUID, &n2.BookUUID, &n2.USN, &n2.AddedOn, &n2.EditedOn, &n2.Body, &n2.Public, &n2.Deleted, &n2.Dirty)
|
||||
|
||||
// execute
|
||||
tx, err := db.Begin()
|
||||
|
|
@ -266,15 +266,15 @@ func TestSyncDeleteNote(t *testing.T) {
|
|||
|
||||
var n2Record core.Note
|
||||
testutils.MustScan(t, "getting n2 for test case",
|
||||
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, content, public, deleted, dirty FROM notes WHERE uuid = ?", n2.UUID),
|
||||
&n2Record.UUID, &n2Record.BookUUID, &n2Record.USN, &n2Record.AddedOn, &n2Record.EditedOn, &n2Record.Content, &n2Record.Public, &n2Record.Deleted, &n2Record.Dirty)
|
||||
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, body, public, deleted, dirty FROM notes WHERE uuid = ?", n2.UUID),
|
||||
&n2Record.UUID, &n2Record.BookUUID, &n2Record.USN, &n2Record.AddedOn, &n2Record.EditedOn, &n2Record.Body, &n2Record.Public, &n2Record.Deleted, &n2Record.Dirty)
|
||||
|
||||
testutils.AssertEqual(t, n2Record.UUID, n2.UUID, "n2 UUID mismatch for test case")
|
||||
testutils.AssertEqual(t, n2Record.BookUUID, n2.BookUUID, "n2 BookUUID mismatch for test case")
|
||||
testutils.AssertEqual(t, n2Record.USN, n2.USN, "n2 USN mismatch for test case")
|
||||
testutils.AssertEqual(t, n2Record.AddedOn, n2.AddedOn, "n2 AddedOn mismatch for test case")
|
||||
testutils.AssertEqual(t, n2Record.EditedOn, n2.EditedOn, "n2 EditedOn mismatch for test case")
|
||||
testutils.AssertEqual(t, n2Record.Content, n2.Content, "n2 Content mismatch for test case")
|
||||
testutils.AssertEqual(t, n2Record.Body, n2.Body, "n2 Body mismatch for test case")
|
||||
testutils.AssertEqual(t, n2Record.Public, n2.Public, "n2 Public mismatch for test case")
|
||||
testutils.AssertEqual(t, n2Record.Deleted, n2.Deleted, "n2 Deleted mismatch for test case")
|
||||
testutils.AssertEqual(t, n2Record.Dirty, n2.Dirty, "n2 Dirty mismatch for test case")
|
||||
|
|
@ -337,7 +337,7 @@ func TestSyncDeleteBook(t *testing.T) {
|
|||
db := ctx.DB
|
||||
|
||||
testutils.MustExec(t, "inserting b1 for test case %d", db, "INSERT INTO books (uuid, label, usn, dirty) VALUES (?, ?, ?, ?)", b1UUID, "b1-label", 12, true)
|
||||
testutils.MustExec(t, "inserting n1 for test case %d", db, "INSERT INTO notes (uuid, book_uuid, usn, content, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", b1UUID, 10, "n1 content", 1541108743, false, true)
|
||||
testutils.MustExec(t, "inserting n1 for test case %d", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", b1UUID, 10, "n1 body", 1541108743, false, true)
|
||||
|
||||
var b1 core.Book
|
||||
testutils.MustScan(t, "getting b1 for test case",
|
||||
|
|
@ -345,8 +345,8 @@ func TestSyncDeleteBook(t *testing.T) {
|
|||
&b1.UUID, &b1.Label, &b1.USN, &b1.Dirty)
|
||||
var n1 core.Note
|
||||
testutils.MustScan(t, "getting n1 for test case",
|
||||
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, content, public, deleted, dirty FROM notes WHERE uuid = ?", "n1-uuid"),
|
||||
&n1.UUID, &n1.BookUUID, &n1.USN, &n1.AddedOn, &n1.EditedOn, &n1.Content, &n1.Public, &n1.Deleted, &n1.Dirty)
|
||||
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, body, public, deleted, dirty FROM notes WHERE uuid = ?", "n1-uuid"),
|
||||
&n1.UUID, &n1.BookUUID, &n1.USN, &n1.AddedOn, &n1.EditedOn, &n1.Body, &n1.Public, &n1.Deleted, &n1.Dirty)
|
||||
|
||||
// execute
|
||||
tx, err := db.Begin()
|
||||
|
|
@ -376,8 +376,8 @@ func TestSyncDeleteBook(t *testing.T) {
|
|||
&b1Record.UUID, &b1Record.Label, &b1Record.USN, &b1Record.Dirty)
|
||||
var n1Record core.Note
|
||||
testutils.MustScan(t, "getting n1 for test case",
|
||||
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, content, public, deleted, dirty FROM notes WHERE uuid = ?", n1.UUID),
|
||||
&n1Record.UUID, &n1Record.BookUUID, &n1Record.USN, &n1Record.AddedOn, &n1Record.EditedOn, &n1Record.Content, &n1Record.Public, &n1Record.Deleted, &n1Record.Dirty)
|
||||
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, body, public, deleted, dirty FROM notes WHERE uuid = ?", n1.UUID),
|
||||
&n1Record.UUID, &n1Record.BookUUID, &n1Record.USN, &n1Record.AddedOn, &n1Record.EditedOn, &n1Record.Body, &n1Record.Public, &n1Record.Deleted, &n1Record.Dirty)
|
||||
|
||||
testutils.AssertEqual(t, b1Record.UUID, b1.UUID, "b1 UUID mismatch for test case")
|
||||
testutils.AssertEqual(t, b1Record.Label, b1.Label, "b1 Label mismatch for test case")
|
||||
|
|
@ -389,7 +389,7 @@ func TestSyncDeleteBook(t *testing.T) {
|
|||
testutils.AssertEqual(t, n1Record.USN, n1.USN, "n1 USN mismatch for test case")
|
||||
testutils.AssertEqual(t, n1Record.AddedOn, n1.AddedOn, "n1 AddedOn mismatch for test case")
|
||||
testutils.AssertEqual(t, n1Record.EditedOn, n1.EditedOn, "n1 EditedOn mismatch for test case")
|
||||
testutils.AssertEqual(t, n1Record.Content, n1.Content, "n1 Content mismatch for test case")
|
||||
testutils.AssertEqual(t, n1Record.Body, n1.Body, "n1 Body mismatch for test case")
|
||||
testutils.AssertEqual(t, n1Record.Public, n1.Public, "n1 Public mismatch for test case")
|
||||
testutils.AssertEqual(t, n1Record.Deleted, n1.Deleted, "n1 Deleted mismatch for test case")
|
||||
testutils.AssertEqual(t, n1Record.Dirty, n1.Dirty, "n1 Dirty mismatch for test case")
|
||||
|
|
@ -406,9 +406,9 @@ func TestSyncDeleteBook(t *testing.T) {
|
|||
db := ctx.DB
|
||||
|
||||
testutils.MustExec(t, "inserting b1 for test case %d", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "b1-label")
|
||||
testutils.MustExec(t, "inserting n1 for test case %d", db, "INSERT INTO notes (uuid, book_uuid, usn, content, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", b1UUID, 10, "n1 content", 1541108743, false, false)
|
||||
testutils.MustExec(t, "inserting n1 for test case %d", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", b1UUID, 10, "n1 body", 1541108743, false, false)
|
||||
testutils.MustExec(t, "inserting b2 for test case %d", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b2UUID, "b2-label")
|
||||
testutils.MustExec(t, "inserting n2 for test case %d", db, "INSERT INTO notes (uuid, book_uuid, usn, content, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n2-uuid", b2UUID, 11, "n2 content", 1541108743, false, false)
|
||||
testutils.MustExec(t, "inserting n2 for test case %d", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n2-uuid", b2UUID, 11, "n2 body", 1541108743, false, false)
|
||||
|
||||
var b2 core.Book
|
||||
testutils.MustScan(t, "getting b2 for test case",
|
||||
|
|
@ -416,8 +416,8 @@ func TestSyncDeleteBook(t *testing.T) {
|
|||
&b2.UUID, &b2.Label, &b2.USN, &b2.Dirty)
|
||||
var n2 core.Note
|
||||
testutils.MustScan(t, "getting n2 for test case",
|
||||
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, content, public, deleted, dirty FROM notes WHERE uuid = ?", "n2-uuid"),
|
||||
&n2.UUID, &n2.BookUUID, &n2.USN, &n2.AddedOn, &n2.EditedOn, &n2.Content, &n2.Public, &n2.Deleted, &n2.Dirty)
|
||||
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, body, public, deleted, dirty FROM notes WHERE uuid = ?", "n2-uuid"),
|
||||
&n2.UUID, &n2.BookUUID, &n2.USN, &n2.AddedOn, &n2.EditedOn, &n2.Body, &n2.Public, &n2.Deleted, &n2.Dirty)
|
||||
|
||||
// execute
|
||||
tx, err := db.Begin()
|
||||
|
|
@ -446,8 +446,8 @@ func TestSyncDeleteBook(t *testing.T) {
|
|||
&b2Record.UUID, &b2Record.Label, &b2Record.USN, &b2Record.Dirty)
|
||||
var n2Record core.Note
|
||||
testutils.MustScan(t, "getting n2 for test case",
|
||||
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, content, public, deleted, dirty FROM notes WHERE uuid = ?", n2.UUID),
|
||||
&n2Record.UUID, &n2Record.BookUUID, &n2Record.USN, &n2Record.AddedOn, &n2Record.EditedOn, &n2Record.Content, &n2Record.Public, &n2Record.Deleted, &n2Record.Dirty)
|
||||
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, body, public, deleted, dirty FROM notes WHERE uuid = ?", n2.UUID),
|
||||
&n2Record.UUID, &n2Record.BookUUID, &n2Record.USN, &n2Record.AddedOn, &n2Record.EditedOn, &n2Record.Body, &n2Record.Public, &n2Record.Deleted, &n2Record.Dirty)
|
||||
|
||||
testutils.AssertEqual(t, b2Record.UUID, b2.UUID, "b2 UUID mismatch for test case")
|
||||
testutils.AssertEqual(t, b2Record.Label, b2.Label, "b2 Label mismatch for test case")
|
||||
|
|
@ -459,7 +459,7 @@ func TestSyncDeleteBook(t *testing.T) {
|
|||
testutils.AssertEqual(t, n2Record.USN, n2.USN, "n2 USN mismatch for test case")
|
||||
testutils.AssertEqual(t, n2Record.AddedOn, n2.AddedOn, "n2 AddedOn mismatch for test case")
|
||||
testutils.AssertEqual(t, n2Record.EditedOn, n2.EditedOn, "n2 EditedOn mismatch for test case")
|
||||
testutils.AssertEqual(t, n2Record.Content, n2.Content, "n2 Content mismatch for test case")
|
||||
testutils.AssertEqual(t, n2Record.Body, n2.Body, "n2 Body mismatch for test case")
|
||||
testutils.AssertEqual(t, n2Record.Public, n2.Public, "n2 Public mismatch for test case")
|
||||
testutils.AssertEqual(t, n2Record.Deleted, n2.Deleted, "n2 Deleted mismatch for test case")
|
||||
testutils.AssertEqual(t, n2Record.Dirty, n2.Dirty, "n2 Dirty mismatch for test case")
|
||||
|
|
@ -475,7 +475,7 @@ func TestSyncDeleteBook(t *testing.T) {
|
|||
db := ctx.DB
|
||||
|
||||
testutils.MustExec(t, "inserting b1 for test case %d", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "b1-label")
|
||||
testutils.MustExec(t, "inserting n1 for test case %d", db, "INSERT INTO notes (uuid, book_uuid, usn, content, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", b1UUID, 10, "n1 content", 1541108743, false, true)
|
||||
testutils.MustExec(t, "inserting n1 for test case %d", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", b1UUID, 10, "n1 body", 1541108743, false, true)
|
||||
|
||||
// execute
|
||||
tx, err := db.Begin()
|
||||
|
|
@ -503,8 +503,8 @@ func TestSyncDeleteBook(t *testing.T) {
|
|||
&b1Record.UUID, &b1Record.Label, &b1Record.USN, &b1Record.Dirty)
|
||||
var n1Record core.Note
|
||||
testutils.MustScan(t, "getting n1 for test case",
|
||||
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, content,deleted, dirty FROM notes WHERE uuid = ?", "n1-uuid"),
|
||||
&n1Record.UUID, &n1Record.BookUUID, &n1Record.USN, &n1Record.AddedOn, &n1Record.Content, &n1Record.Deleted, &n1Record.Dirty)
|
||||
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, body,deleted, dirty FROM notes WHERE uuid = ?", "n1-uuid"),
|
||||
&n1Record.UUID, &n1Record.BookUUID, &n1Record.USN, &n1Record.AddedOn, &n1Record.Body, &n1Record.Deleted, &n1Record.Dirty)
|
||||
|
||||
testutils.AssertEqual(t, b1Record.UUID, b1UUID, "b1 UUID mismatch for test case")
|
||||
testutils.AssertEqual(t, b1Record.Label, "b1-label", "b1 Label mismatch for test case")
|
||||
|
|
@ -514,7 +514,7 @@ func TestSyncDeleteBook(t *testing.T) {
|
|||
testutils.AssertEqual(t, n1Record.BookUUID, b1UUID, "n1 BookUUID mismatch for test case")
|
||||
testutils.AssertEqual(t, n1Record.USN, 10, "n1 USN mismatch for test case")
|
||||
testutils.AssertEqual(t, n1Record.AddedOn, int64(1541108743), "n1 AddedOn mismatch for test case")
|
||||
testutils.AssertEqual(t, n1Record.Content, "n1 content", "n1 Content mismatch for test case")
|
||||
testutils.AssertEqual(t, n1Record.Body, "n1 body", "n1 Body mismatch for test case")
|
||||
testutils.AssertEqual(t, n1Record.Deleted, false, "n1 Deleted mismatch for test case")
|
||||
testutils.AssertEqual(t, n1Record.Dirty, true, "n1 Dirty mismatch for test case")
|
||||
})
|
||||
|
|
@ -543,7 +543,7 @@ func TestFullSyncNote(t *testing.T) {
|
|||
USN: 128,
|
||||
AddedOn: 1541232118,
|
||||
EditedOn: 1541219321,
|
||||
Content: "n1-content",
|
||||
Body: "n1-body",
|
||||
Public: true,
|
||||
Deleted: false,
|
||||
}
|
||||
|
|
@ -565,15 +565,15 @@ func TestFullSyncNote(t *testing.T) {
|
|||
|
||||
var n1 core.Note
|
||||
testutils.MustScan(t, "getting n1",
|
||||
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, content, public, deleted, dirty FROM notes WHERE uuid = ?", n.UUID),
|
||||
&n1.UUID, &n1.BookUUID, &n1.USN, &n1.AddedOn, &n1.EditedOn, &n1.Content, &n1.Public, &n1.Deleted, &n1.Dirty)
|
||||
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, body, public, deleted, dirty FROM notes WHERE uuid = ?", n.UUID),
|
||||
&n1.UUID, &n1.BookUUID, &n1.USN, &n1.AddedOn, &n1.EditedOn, &n1.Body, &n1.Public, &n1.Deleted, &n1.Dirty)
|
||||
|
||||
testutils.AssertEqual(t, n1.UUID, n.UUID, "n1 UUID mismatch")
|
||||
testutils.AssertEqual(t, n1.BookUUID, n.BookUUID, "n1 BookUUID mismatch")
|
||||
testutils.AssertEqual(t, n1.USN, n.USN, "n1 USN mismatch")
|
||||
testutils.AssertEqual(t, n1.AddedOn, n.AddedOn, "n1 AddedOn mismatch")
|
||||
testutils.AssertEqual(t, n1.EditedOn, n.EditedOn, "n1 EditedOn mismatch")
|
||||
testutils.AssertEqual(t, n1.Content, n.Content, "n1 Content mismatch")
|
||||
testutils.AssertEqual(t, n1.Body, n.Body, "n1 Body mismatch")
|
||||
testutils.AssertEqual(t, n1.Public, n.Public, "n1 Public mismatch")
|
||||
testutils.AssertEqual(t, n1.Deleted, n.Deleted, "n1 Deleted mismatch")
|
||||
testutils.AssertEqual(t, n1.Dirty, false, "n1 Dirty mismatch")
|
||||
|
|
@ -587,21 +587,21 @@ func TestFullSyncNote(t *testing.T) {
|
|||
addedOn int64
|
||||
clientUSN int
|
||||
clientEditedOn int64
|
||||
clientContent string
|
||||
clientBody string
|
||||
clientPublic bool
|
||||
clientDeleted bool
|
||||
clientBookUUID string
|
||||
clientDirty bool
|
||||
serverUSN int
|
||||
serverEditedOn int64
|
||||
serverContent string
|
||||
serverBody string
|
||||
serverPublic bool
|
||||
serverDeleted bool
|
||||
serverBookUUID string
|
||||
expectedUSN int
|
||||
expectedAddedOn int64
|
||||
expectedEditedOn int64
|
||||
expectedContent string
|
||||
expectedBody string
|
||||
expectedPublic bool
|
||||
expectedDeleted bool
|
||||
expectedBookUUID string
|
||||
|
|
@ -612,21 +612,21 @@ func TestFullSyncNote(t *testing.T) {
|
|||
clientDirty: true,
|
||||
clientUSN: 1,
|
||||
clientEditedOn: 0,
|
||||
clientContent: "n1 content",
|
||||
clientBody: "n1 body",
|
||||
clientPublic: false,
|
||||
clientDeleted: false,
|
||||
clientBookUUID: b1UUID,
|
||||
addedOn: 1541232118,
|
||||
serverUSN: 21,
|
||||
serverEditedOn: 1541219321,
|
||||
serverContent: "n1 content edited",
|
||||
serverBody: "n1 body edited",
|
||||
serverPublic: true,
|
||||
serverDeleted: false,
|
||||
serverBookUUID: b2UUID,
|
||||
expectedUSN: 21,
|
||||
expectedAddedOn: 1541232118,
|
||||
expectedEditedOn: 1541219321,
|
||||
expectedContent: "n1 content edited",
|
||||
expectedBody: "n1 body edited",
|
||||
expectedPublic: true,
|
||||
expectedDeleted: false,
|
||||
expectedBookUUID: b2UUID,
|
||||
|
|
@ -637,21 +637,21 @@ func TestFullSyncNote(t *testing.T) {
|
|||
clientDirty: true,
|
||||
clientUSN: 1,
|
||||
clientEditedOn: 0,
|
||||
clientContent: "",
|
||||
clientBody: "",
|
||||
clientPublic: false,
|
||||
clientDeleted: true,
|
||||
clientBookUUID: b1UUID,
|
||||
addedOn: 1541232118,
|
||||
serverUSN: 21,
|
||||
serverEditedOn: 1541219321,
|
||||
serverContent: "n1 content server",
|
||||
serverBody: "n1 body server",
|
||||
serverPublic: false,
|
||||
serverDeleted: false,
|
||||
serverBookUUID: b2UUID,
|
||||
expectedUSN: 21,
|
||||
expectedAddedOn: 1541232118,
|
||||
expectedEditedOn: 1541219321,
|
||||
expectedContent: "n1 content server",
|
||||
expectedBody: "n1 body server",
|
||||
expectedPublic: false,
|
||||
expectedDeleted: false,
|
||||
expectedBookUUID: b2UUID,
|
||||
|
|
@ -662,21 +662,21 @@ func TestFullSyncNote(t *testing.T) {
|
|||
clientDirty: false,
|
||||
clientUSN: 1,
|
||||
clientEditedOn: 0,
|
||||
clientContent: "n1 content",
|
||||
clientBody: "n1 body",
|
||||
clientPublic: false,
|
||||
clientDeleted: false,
|
||||
clientBookUUID: b1UUID,
|
||||
addedOn: 1541232118,
|
||||
serverUSN: 21,
|
||||
serverEditedOn: 1541219321,
|
||||
serverContent: "n1 content edited",
|
||||
serverBody: "n1 body edited",
|
||||
serverPublic: true,
|
||||
serverDeleted: false,
|
||||
serverBookUUID: b2UUID,
|
||||
expectedUSN: 21,
|
||||
expectedAddedOn: 1541232118,
|
||||
expectedEditedOn: 1541219321,
|
||||
expectedContent: "n1 content edited",
|
||||
expectedBody: "n1 body edited",
|
||||
expectedPublic: true,
|
||||
expectedDeleted: false,
|
||||
expectedBookUUID: b2UUID,
|
||||
|
|
@ -687,21 +687,21 @@ func TestFullSyncNote(t *testing.T) {
|
|||
clientDirty: true,
|
||||
clientUSN: 21,
|
||||
clientEditedOn: 1541219321,
|
||||
clientContent: "n1 content",
|
||||
clientBody: "n1 body",
|
||||
clientPublic: false,
|
||||
clientDeleted: false,
|
||||
clientBookUUID: b2UUID,
|
||||
addedOn: 1541232118,
|
||||
serverUSN: 21,
|
||||
serverEditedOn: 1541219321,
|
||||
serverContent: "n1 content",
|
||||
serverBody: "n1 body",
|
||||
serverPublic: false,
|
||||
serverDeleted: false,
|
||||
serverBookUUID: b2UUID,
|
||||
expectedUSN: 21,
|
||||
expectedAddedOn: 1541232118,
|
||||
expectedEditedOn: 1541219321,
|
||||
expectedContent: "n1 content",
|
||||
expectedBody: "n1 body",
|
||||
expectedPublic: false,
|
||||
expectedDeleted: false,
|
||||
expectedBookUUID: b2UUID,
|
||||
|
|
@ -714,21 +714,21 @@ func TestFullSyncNote(t *testing.T) {
|
|||
clientDirty: true,
|
||||
clientUSN: 21,
|
||||
clientEditedOn: 1541219320,
|
||||
clientContent: "n1 content client",
|
||||
clientBody: "n1 body client",
|
||||
clientPublic: false,
|
||||
clientDeleted: false,
|
||||
clientBookUUID: b2UUID,
|
||||
addedOn: 1541232118,
|
||||
serverUSN: 21,
|
||||
serverEditedOn: 1541219321,
|
||||
serverContent: "n1 content server",
|
||||
serverBody: "n1 body server",
|
||||
serverPublic: true,
|
||||
serverDeleted: false,
|
||||
serverBookUUID: b2UUID,
|
||||
expectedUSN: 21,
|
||||
expectedAddedOn: 1541232118,
|
||||
expectedEditedOn: 1541219320,
|
||||
expectedContent: "n1 content client",
|
||||
expectedBody: "n1 body client",
|
||||
expectedPublic: false,
|
||||
expectedDeleted: false,
|
||||
expectedBookUUID: b2UUID,
|
||||
|
|
@ -747,7 +747,7 @@ func TestFullSyncNote(t *testing.T) {
|
|||
testutils.MustExec(t, fmt.Sprintf("inserting b1 for test case %d", idx), db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "b1-label")
|
||||
testutils.MustExec(t, fmt.Sprintf("inserting b2 for test case %d", idx), db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b2UUID, "b2-label")
|
||||
n1UUID := utils.GenerateUUID()
|
||||
testutils.MustExec(t, fmt.Sprintf("inserting n1 for test case %d", idx), db, "INSERT INTO notes (uuid, book_uuid, usn, added_on, edited_on, content, public, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", n1UUID, tc.clientBookUUID, tc.clientUSN, tc.addedOn, tc.clientEditedOn, tc.clientContent, tc.clientPublic, tc.clientDeleted, tc.clientDirty)
|
||||
testutils.MustExec(t, fmt.Sprintf("inserting n1 for test case %d", idx), db, "INSERT INTO notes (uuid, book_uuid, usn, added_on, edited_on, body, public, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", n1UUID, tc.clientBookUUID, tc.clientUSN, tc.addedOn, tc.clientEditedOn, tc.clientBody, tc.clientPublic, tc.clientDeleted, tc.clientDirty)
|
||||
|
||||
// execute
|
||||
tx, err := db.Begin()
|
||||
|
|
@ -762,7 +762,7 @@ func TestFullSyncNote(t *testing.T) {
|
|||
USN: tc.serverUSN,
|
||||
AddedOn: tc.addedOn,
|
||||
EditedOn: tc.serverEditedOn,
|
||||
Content: tc.serverContent,
|
||||
Body: tc.serverBody,
|
||||
Public: tc.serverPublic,
|
||||
Deleted: tc.serverDeleted,
|
||||
}
|
||||
|
|
@ -784,15 +784,15 @@ func TestFullSyncNote(t *testing.T) {
|
|||
|
||||
var n1 core.Note
|
||||
testutils.MustScan(t, fmt.Sprintf("getting n1 for test case %d", idx),
|
||||
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, content, public, deleted, dirty FROM notes WHERE uuid = ?", n.UUID),
|
||||
&n1.UUID, &n1.BookUUID, &n1.USN, &n1.AddedOn, &n1.EditedOn, &n1.Content, &n1.Public, &n1.Deleted, &n1.Dirty)
|
||||
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, body, public, deleted, dirty FROM notes WHERE uuid = ?", n.UUID),
|
||||
&n1.UUID, &n1.BookUUID, &n1.USN, &n1.AddedOn, &n1.EditedOn, &n1.Body, &n1.Public, &n1.Deleted, &n1.Dirty)
|
||||
|
||||
testutils.AssertEqual(t, n1.UUID, n.UUID, fmt.Sprintf("n1 UUID mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, n1.BookUUID, tc.expectedBookUUID, fmt.Sprintf("n1 BookUUID mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, n1.USN, tc.expectedUSN, fmt.Sprintf("n1 USN mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, n1.AddedOn, tc.expectedAddedOn, fmt.Sprintf("n1 AddedOn mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, n1.EditedOn, tc.expectedEditedOn, fmt.Sprintf("n1 EditedOn mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, n1.Content, tc.expectedContent, fmt.Sprintf("n1 Content mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, n1.Body, tc.expectedBody, fmt.Sprintf("n1 Body mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, n1.Public, tc.expectedPublic, fmt.Sprintf("n1 Public mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, n1.Deleted, tc.expectedDeleted, fmt.Sprintf("n1 Deleted mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, n1.Dirty, tc.expectedDirty, fmt.Sprintf("n1 Dirty mismatch for test case %d", idx))
|
||||
|
|
@ -1020,7 +1020,7 @@ func TestStepSyncNote(t *testing.T) {
|
|||
USN: 128,
|
||||
AddedOn: 1541232118,
|
||||
EditedOn: 1541219321,
|
||||
Content: "n1-content",
|
||||
Body: "n1-body",
|
||||
Public: true,
|
||||
Deleted: false,
|
||||
}
|
||||
|
|
@ -1042,15 +1042,15 @@ func TestStepSyncNote(t *testing.T) {
|
|||
|
||||
var n1 core.Note
|
||||
testutils.MustScan(t, "getting n1",
|
||||
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, content, public, deleted, dirty FROM notes WHERE uuid = ?", n.UUID),
|
||||
&n1.UUID, &n1.BookUUID, &n1.USN, &n1.AddedOn, &n1.EditedOn, &n1.Content, &n1.Public, &n1.Deleted, &n1.Dirty)
|
||||
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, body, public, deleted, dirty FROM notes WHERE uuid = ?", n.UUID),
|
||||
&n1.UUID, &n1.BookUUID, &n1.USN, &n1.AddedOn, &n1.EditedOn, &n1.Body, &n1.Public, &n1.Deleted, &n1.Dirty)
|
||||
|
||||
testutils.AssertEqual(t, n1.UUID, n.UUID, "n1 UUID mismatch")
|
||||
testutils.AssertEqual(t, n1.BookUUID, n.BookUUID, "n1 BookUUID mismatch")
|
||||
testutils.AssertEqual(t, n1.USN, n.USN, "n1 USN mismatch")
|
||||
testutils.AssertEqual(t, n1.AddedOn, n.AddedOn, "n1 AddedOn mismatch")
|
||||
testutils.AssertEqual(t, n1.EditedOn, n.EditedOn, "n1 EditedOn mismatch")
|
||||
testutils.AssertEqual(t, n1.Content, n.Content, "n1 Content mismatch")
|
||||
testutils.AssertEqual(t, n1.Body, n.Body, "n1 Body mismatch")
|
||||
testutils.AssertEqual(t, n1.Public, n.Public, "n1 Public mismatch")
|
||||
testutils.AssertEqual(t, n1.Deleted, n.Deleted, "n1 Deleted mismatch")
|
||||
testutils.AssertEqual(t, n1.Dirty, false, "n1 Dirty mismatch")
|
||||
|
|
@ -1064,21 +1064,21 @@ func TestStepSyncNote(t *testing.T) {
|
|||
addedOn int64
|
||||
clientUSN int
|
||||
clientEditedOn int64
|
||||
clientContent string
|
||||
clientBody string
|
||||
clientPublic bool
|
||||
clientDeleted bool
|
||||
clientBookUUID string
|
||||
clientDirty bool
|
||||
serverUSN int
|
||||
serverEditedOn int64
|
||||
serverContent string
|
||||
serverBody string
|
||||
serverPublic bool
|
||||
serverDeleted bool
|
||||
serverBookUUID string
|
||||
expectedUSN int
|
||||
expectedAddedOn int64
|
||||
expectedEditedOn int64
|
||||
expectedContent string
|
||||
expectedBody string
|
||||
expectedPublic bool
|
||||
expectedDeleted bool
|
||||
expectedBookUUID string
|
||||
|
|
@ -1088,21 +1088,21 @@ func TestStepSyncNote(t *testing.T) {
|
|||
clientDirty: true,
|
||||
clientUSN: 1,
|
||||
clientEditedOn: 0,
|
||||
clientContent: "n1 content",
|
||||
clientBody: "n1 body",
|
||||
clientPublic: false,
|
||||
clientDeleted: false,
|
||||
clientBookUUID: b1UUID,
|
||||
addedOn: 1541232118,
|
||||
serverUSN: 21,
|
||||
serverEditedOn: 1541219321,
|
||||
serverContent: "n1 content edited",
|
||||
serverBody: "n1 body edited",
|
||||
serverPublic: true,
|
||||
serverDeleted: false,
|
||||
serverBookUUID: b2UUID,
|
||||
expectedUSN: 21,
|
||||
expectedAddedOn: 1541232118,
|
||||
expectedEditedOn: 1541219321,
|
||||
expectedContent: "n1 content edited",
|
||||
expectedBody: "n1 body edited",
|
||||
expectedPublic: true,
|
||||
expectedDeleted: false,
|
||||
expectedBookUUID: b2UUID,
|
||||
|
|
@ -1113,21 +1113,21 @@ func TestStepSyncNote(t *testing.T) {
|
|||
clientDirty: true,
|
||||
clientUSN: 1,
|
||||
clientEditedOn: 1541219321,
|
||||
clientContent: "",
|
||||
clientBody: "",
|
||||
clientPublic: false,
|
||||
clientDeleted: true,
|
||||
clientBookUUID: b1UUID,
|
||||
addedOn: 1541232118,
|
||||
serverUSN: 21,
|
||||
serverEditedOn: 1541219321,
|
||||
serverContent: "n1 content edited",
|
||||
serverBody: "n1 body edited",
|
||||
serverPublic: false,
|
||||
serverDeleted: false,
|
||||
serverBookUUID: b2UUID,
|
||||
expectedUSN: 21,
|
||||
expectedAddedOn: 1541232118,
|
||||
expectedEditedOn: 1541219321,
|
||||
expectedContent: "n1 content edited",
|
||||
expectedBody: "n1 body edited",
|
||||
expectedPublic: false,
|
||||
expectedDeleted: false,
|
||||
expectedBookUUID: b2UUID,
|
||||
|
|
@ -1137,21 +1137,21 @@ func TestStepSyncNote(t *testing.T) {
|
|||
clientDirty: false,
|
||||
clientUSN: 1,
|
||||
clientEditedOn: 0,
|
||||
clientContent: "n1 content",
|
||||
clientBody: "n1 body",
|
||||
clientPublic: false,
|
||||
clientDeleted: false,
|
||||
clientBookUUID: b1UUID,
|
||||
addedOn: 1541232118,
|
||||
serverUSN: 21,
|
||||
serverEditedOn: 1541219321,
|
||||
serverContent: "n1 content edited",
|
||||
serverBody: "n1 body edited",
|
||||
serverPublic: true,
|
||||
serverDeleted: false,
|
||||
serverBookUUID: b2UUID,
|
||||
expectedUSN: 21,
|
||||
expectedAddedOn: 1541232118,
|
||||
expectedEditedOn: 1541219321,
|
||||
expectedContent: "n1 content edited",
|
||||
expectedBody: "n1 body edited",
|
||||
expectedPublic: true,
|
||||
expectedDeleted: false,
|
||||
expectedBookUUID: b2UUID,
|
||||
|
|
@ -1170,7 +1170,7 @@ func TestStepSyncNote(t *testing.T) {
|
|||
testutils.MustExec(t, fmt.Sprintf("inserting b1 for test case %d", idx), db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "b1-label")
|
||||
testutils.MustExec(t, fmt.Sprintf("inserting b2 for test case %d", idx), db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b2UUID, "b2-label")
|
||||
n1UUID := utils.GenerateUUID()
|
||||
testutils.MustExec(t, fmt.Sprintf("inserting n1 for test case %d", idx), db, "INSERT INTO notes (uuid, book_uuid, usn, added_on, edited_on, content, public, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", n1UUID, tc.clientBookUUID, tc.clientUSN, tc.addedOn, tc.clientEditedOn, tc.clientContent, tc.clientPublic, tc.clientDeleted, tc.clientDirty)
|
||||
testutils.MustExec(t, fmt.Sprintf("inserting n1 for test case %d", idx), db, "INSERT INTO notes (uuid, book_uuid, usn, added_on, edited_on, body, public, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", n1UUID, tc.clientBookUUID, tc.clientUSN, tc.addedOn, tc.clientEditedOn, tc.clientBody, tc.clientPublic, tc.clientDeleted, tc.clientDirty)
|
||||
|
||||
// execute
|
||||
tx, err := db.Begin()
|
||||
|
|
@ -1185,7 +1185,7 @@ func TestStepSyncNote(t *testing.T) {
|
|||
USN: tc.serverUSN,
|
||||
AddedOn: tc.addedOn,
|
||||
EditedOn: tc.serverEditedOn,
|
||||
Content: tc.serverContent,
|
||||
Body: tc.serverBody,
|
||||
Public: tc.serverPublic,
|
||||
Deleted: tc.serverDeleted,
|
||||
}
|
||||
|
|
@ -1207,15 +1207,15 @@ func TestStepSyncNote(t *testing.T) {
|
|||
|
||||
var n1 core.Note
|
||||
testutils.MustScan(t, fmt.Sprintf("getting n1 for test case %d", idx),
|
||||
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, content, public, deleted, dirty FROM notes WHERE uuid = ?", n.UUID),
|
||||
&n1.UUID, &n1.BookUUID, &n1.USN, &n1.AddedOn, &n1.EditedOn, &n1.Content, &n1.Public, &n1.Deleted, &n1.Dirty)
|
||||
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, body, public, deleted, dirty FROM notes WHERE uuid = ?", n.UUID),
|
||||
&n1.UUID, &n1.BookUUID, &n1.USN, &n1.AddedOn, &n1.EditedOn, &n1.Body, &n1.Public, &n1.Deleted, &n1.Dirty)
|
||||
|
||||
testutils.AssertEqual(t, n1.UUID, n.UUID, fmt.Sprintf("n1 UUID mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, n1.BookUUID, tc.expectedBookUUID, fmt.Sprintf("n1 BookUUID mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, n1.USN, tc.expectedUSN, fmt.Sprintf("n1 USN mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, n1.AddedOn, tc.expectedAddedOn, fmt.Sprintf("n1 AddedOn mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, n1.EditedOn, tc.expectedEditedOn, fmt.Sprintf("n1 EditedOn mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, n1.Content, tc.expectedContent, fmt.Sprintf("n1 Content mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, n1.Body, tc.expectedBody, fmt.Sprintf("n1 Body mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, n1.Public, tc.expectedPublic, fmt.Sprintf("n1 Public mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, n1.Deleted, tc.expectedDeleted, fmt.Sprintf("n1 Deleted mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, n1.Dirty, tc.expectedDirty, fmt.Sprintf("n1 Dirty mismatch for test case %d", idx))
|
||||
|
|
@ -1833,14 +1833,14 @@ func TestSendBooks(t *testing.T) {
|
|||
testutils.MustExec(t, "inserting b8", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b8-uuid", "b8-label", 18, false, true)
|
||||
|
||||
// some random notes
|
||||
testutils.MustExec(t, "inserting n1", db, "INSERT INTO notes (uuid, book_uuid, usn, content, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", "b1-uuid", 10, "n1 content", 1541108743, false, false)
|
||||
testutils.MustExec(t, "inserting n2", db, "INSERT INTO notes (uuid, book_uuid, usn, content, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n2-uuid", "b5-uuid", 10, "n2 content", 1541108743, false, false)
|
||||
testutils.MustExec(t, "inserting n3", db, "INSERT INTO notes (uuid, book_uuid, usn, content, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n3-uuid", "b6-uuid", 10, "n3 content", 1541108743, false, false)
|
||||
testutils.MustExec(t, "inserting n4", db, "INSERT INTO notes (uuid, book_uuid, usn, content, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n4-uuid", "b7-uuid", 10, "n4 content", 1541108743, false, false)
|
||||
testutils.MustExec(t, "inserting n1", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", "b1-uuid", 10, "n1 body", 1541108743, false, false)
|
||||
testutils.MustExec(t, "inserting n2", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n2-uuid", "b5-uuid", 10, "n2 body", 1541108743, false, false)
|
||||
testutils.MustExec(t, "inserting n3", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n3-uuid", "b6-uuid", 10, "n3 body", 1541108743, false, false)
|
||||
testutils.MustExec(t, "inserting n4", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n4-uuid", "b7-uuid", 10, "n4 body", 1541108743, false, false)
|
||||
// notes that belong to the created book. Their book_uuid should be updated.
|
||||
testutils.MustExec(t, "inserting n5", db, "INSERT INTO notes (uuid, book_uuid, usn, content, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n5-uuid", "b3-uuid", 10, "n5 content", 1541108743, false, false)
|
||||
testutils.MustExec(t, "inserting n6", db, "INSERT INTO notes (uuid, book_uuid, usn, content, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n6-uuid", "b3-uuid", 10, "n6 content", 1541108743, false, false)
|
||||
testutils.MustExec(t, "inserting n7", db, "INSERT INTO notes (uuid, book_uuid, usn, content, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n7-uuid", "b4-uuid", 10, "n7 content", 1541108743, false, false)
|
||||
testutils.MustExec(t, "inserting n5", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n5-uuid", "b3-uuid", 10, "n5 body", 1541108743, false, false)
|
||||
testutils.MustExec(t, "inserting n6", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n6-uuid", "b3-uuid", 10, "n6 body", 1541108743, false, false)
|
||||
testutils.MustExec(t, "inserting n7", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n7-uuid", "b4-uuid", 10, "n7 body", 1541108743, false, false)
|
||||
|
||||
var createdLabels []string
|
||||
var updatesUUIDs []string
|
||||
|
|
@ -1865,7 +1865,7 @@ func TestSendBooks(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Header().Set("Body-Type", "application/json")
|
||||
if err := json.NewEncoder(w).Encode(resp); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
|
|
@ -1879,14 +1879,14 @@ func TestSendBooks(t *testing.T) {
|
|||
uuid := p[3]
|
||||
updatesUUIDs = append(updatesUUIDs, uuid)
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Header().Set("Body-Type", "application/json")
|
||||
w.Write([]byte("{}"))
|
||||
return
|
||||
} else if r.Method == "DELETE" {
|
||||
uuid := p[3]
|
||||
deletedUUIDs = append(deletedUUIDs, uuid)
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Header().Set("Body-Type", "application/json")
|
||||
w.Write([]byte("{}"))
|
||||
return
|
||||
}
|
||||
|
|
@ -1946,13 +1946,13 @@ func TestSendBooks(t *testing.T) {
|
|||
testutils.AssertEqual(t, b8.UUID, "b8-uuid", "b8 UUID mismatch")
|
||||
|
||||
var n1, n2, n3, n4, n5, n6, n7 core.Note
|
||||
testutils.MustScan(t, "getting n1", db.QueryRow("SELECT book_uuid FROM notes WHERE content = ?", "n1 content"), &n1.BookUUID)
|
||||
testutils.MustScan(t, "getting n2", db.QueryRow("SELECT book_uuid FROM notes WHERE content = ?", "n2 content"), &n2.BookUUID)
|
||||
testutils.MustScan(t, "getting n3", db.QueryRow("SELECT book_uuid FROM notes WHERE content = ?", "n3 content"), &n3.BookUUID)
|
||||
testutils.MustScan(t, "getting n4", db.QueryRow("SELECT book_uuid FROM notes WHERE content = ?", "n4 content"), &n4.BookUUID)
|
||||
testutils.MustScan(t, "getting n5", db.QueryRow("SELECT book_uuid FROM notes WHERE content = ?", "n5 content"), &n5.BookUUID)
|
||||
testutils.MustScan(t, "getting n6", db.QueryRow("SELECT book_uuid FROM notes WHERE content = ?", "n6 content"), &n6.BookUUID)
|
||||
testutils.MustScan(t, "getting n7", db.QueryRow("SELECT book_uuid FROM notes WHERE content = ?", "n7 content"), &n7.BookUUID)
|
||||
testutils.MustScan(t, "getting n1", db.QueryRow("SELECT book_uuid FROM notes WHERE body = ?", "n1 body"), &n1.BookUUID)
|
||||
testutils.MustScan(t, "getting n2", db.QueryRow("SELECT book_uuid FROM notes WHERE body = ?", "n2 body"), &n2.BookUUID)
|
||||
testutils.MustScan(t, "getting n3", db.QueryRow("SELECT book_uuid FROM notes WHERE body = ?", "n3 body"), &n3.BookUUID)
|
||||
testutils.MustScan(t, "getting n4", db.QueryRow("SELECT book_uuid FROM notes WHERE body = ?", "n4 body"), &n4.BookUUID)
|
||||
testutils.MustScan(t, "getting n5", db.QueryRow("SELECT book_uuid FROM notes WHERE body = ?", "n5 body"), &n5.BookUUID)
|
||||
testutils.MustScan(t, "getting n6", db.QueryRow("SELECT book_uuid FROM notes WHERE body = ?", "n6 body"), &n6.BookUUID)
|
||||
testutils.MustScan(t, "getting n7", db.QueryRow("SELECT book_uuid FROM notes WHERE body = ?", "n7 body"), &n7.BookUUID)
|
||||
testutils.AssertEqual(t, n1.BookUUID, "b1-uuid", "n1 bookUUID mismatch")
|
||||
testutils.AssertEqual(t, n2.BookUUID, "b5-uuid", "n2 bookUUID mismatch")
|
||||
testutils.AssertEqual(t, n3.BookUUID, "b6-uuid", "n3 bookUUID mismatch")
|
||||
|
|
@ -1979,7 +1979,7 @@ func TestSendBooks_isBehind(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Header().Set("Body-Type", "application/json")
|
||||
if err := json.NewEncoder(w).Encode(resp); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
|
|
@ -1996,7 +1996,7 @@ func TestSendBooks_isBehind(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Header().Set("Body-Type", "application/json")
|
||||
if err := json.NewEncoder(w).Encode(resp); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
|
|
@ -2009,7 +2009,7 @@ func TestSendBooks_isBehind(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Header().Set("Body-Type", "application/json")
|
||||
if err := json.NewEncoder(w).Encode(resp); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
|
|
@ -2179,27 +2179,27 @@ func TestSendNotes(t *testing.T) {
|
|||
testutils.MustExec(t, "inserting b1", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", b1UUID, "b1-label", 1, false, false)
|
||||
|
||||
// should be ignored
|
||||
testutils.MustExec(t, "inserting n1", db, "INSERT INTO notes (uuid, book_uuid, usn, content, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", b1UUID, 10, "n1-content", 1541108743, false, false)
|
||||
testutils.MustExec(t, "inserting n1", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", b1UUID, 10, "n1-body", 1541108743, false, false)
|
||||
// should be created
|
||||
testutils.MustExec(t, "inserting n2", db, "INSERT INTO notes (uuid, book_uuid, usn, content, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n2-uuid", b1UUID, 0, "n2-content", 1541108743, false, true)
|
||||
testutils.MustExec(t, "inserting n2", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n2-uuid", b1UUID, 0, "n2-body", 1541108743, false, true)
|
||||
// should be updated
|
||||
testutils.MustExec(t, "inserting n3", db, "INSERT INTO notes (uuid, book_uuid, usn, content, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n3-uuid", b1UUID, 11, "n3-content", 1541108743, false, true)
|
||||
testutils.MustExec(t, "inserting n3", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n3-uuid", b1UUID, 11, "n3-body", 1541108743, false, true)
|
||||
// should be only expunged locally without syncing to server
|
||||
testutils.MustExec(t, "inserting n4", db, "INSERT INTO notes (uuid, book_uuid, usn, content, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n4-uuid", b1UUID, 0, "n4-content", 1541108743, true, true)
|
||||
testutils.MustExec(t, "inserting n4", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n4-uuid", b1UUID, 0, "n4-body", 1541108743, true, true)
|
||||
// should be deleted
|
||||
testutils.MustExec(t, "inserting n5", db, "INSERT INTO notes (uuid, book_uuid, usn, content, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n5-uuid", b1UUID, 17, "n5-content", 1541108743, true, true)
|
||||
testutils.MustExec(t, "inserting n5", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n5-uuid", b1UUID, 17, "n5-body", 1541108743, true, true)
|
||||
// should be created
|
||||
testutils.MustExec(t, "inserting n6", db, "INSERT INTO notes (uuid, book_uuid, usn, content, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n6-uuid", b1UUID, 0, "n6-content", 1541108743, false, true)
|
||||
testutils.MustExec(t, "inserting n6", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n6-uuid", b1UUID, 0, "n6-body", 1541108743, false, true)
|
||||
// should be ignored
|
||||
testutils.MustExec(t, "inserting n7", db, "INSERT INTO notes (uuid, book_uuid, usn, content, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n7-uuid", b1UUID, 12, "n7-content", 1541108743, false, false)
|
||||
testutils.MustExec(t, "inserting n7", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n7-uuid", b1UUID, 12, "n7-body", 1541108743, false, false)
|
||||
// should be updated
|
||||
testutils.MustExec(t, "inserting n8", db, "INSERT INTO notes (uuid, book_uuid, usn, content, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n8-uuid", b1UUID, 17, "n8-content", 1541108743, false, true)
|
||||
testutils.MustExec(t, "inserting n8", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n8-uuid", b1UUID, 17, "n8-body", 1541108743, false, true)
|
||||
// should be deleted
|
||||
testutils.MustExec(t, "inserting n9", db, "INSERT INTO notes (uuid, book_uuid, usn, content, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n9-uuid", b1UUID, 17, "n9-content", 1541108743, true, true)
|
||||
testutils.MustExec(t, "inserting n9", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n9-uuid", b1UUID, 17, "n9-body", 1541108743, true, true)
|
||||
// should be created
|
||||
testutils.MustExec(t, "inserting n10", db, "INSERT INTO notes (uuid, book_uuid, usn, content, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n10-uuid", b1UUID, 0, "n10-content", 1541108743, false, true)
|
||||
testutils.MustExec(t, "inserting n10", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n10-uuid", b1UUID, 0, "n10-body", 1541108743, false, true)
|
||||
|
||||
var createdContents []string
|
||||
var createdBodys []string
|
||||
var updatedUUIDs []string
|
||||
var deletedUUIDs []string
|
||||
|
||||
|
|
@ -2214,15 +2214,15 @@ func TestSendNotes(t *testing.T) {
|
|||
return
|
||||
}
|
||||
|
||||
createdContents = append(createdContents, payload.Content)
|
||||
createdBodys = append(createdBodys, payload.Body)
|
||||
|
||||
resp := client.CreateNoteResp{
|
||||
Result: client.RespNote{
|
||||
UUID: fmt.Sprintf("server-%s-uuid", payload.Content),
|
||||
UUID: fmt.Sprintf("server-%s-uuid", payload.Body),
|
||||
},
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Header().Set("Body-Type", "application/json")
|
||||
if err := json.NewEncoder(w).Encode(resp); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
|
|
@ -2236,14 +2236,14 @@ func TestSendNotes(t *testing.T) {
|
|||
uuid := p[3]
|
||||
updatedUUIDs = append(updatedUUIDs, uuid)
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Header().Set("Body-Type", "application/json")
|
||||
w.Write([]byte("{}"))
|
||||
return
|
||||
} else if r.Method == "DELETE" {
|
||||
uuid := p[3]
|
||||
deletedUUIDs = append(deletedUUIDs, uuid)
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Header().Set("Body-Type", "application/json")
|
||||
w.Write([]byte("{}"))
|
||||
return
|
||||
}
|
||||
|
|
@ -2269,11 +2269,11 @@ func TestSendNotes(t *testing.T) {
|
|||
tx.Commit()
|
||||
|
||||
// test
|
||||
sort.SliceStable(createdContents, func(i, j int) bool {
|
||||
return strings.Compare(createdContents[i], createdContents[j]) < 0
|
||||
sort.SliceStable(createdBodys, func(i, j int) bool {
|
||||
return strings.Compare(createdBodys[i], createdBodys[j]) < 0
|
||||
})
|
||||
|
||||
testutils.AssertDeepEqual(t, createdContents, []string{"n10-content", "n2-content", "n6-content"}, "createdContents mismatch")
|
||||
testutils.AssertDeepEqual(t, createdBodys, []string{"n10-body", "n2-body", "n6-body"}, "createdBodys mismatch")
|
||||
testutils.AssertDeepEqual(t, updatedUUIDs, []string{"n3-uuid", "n8-uuid"}, "updatedUUIDs mismatch")
|
||||
testutils.AssertDeepEqual(t, deletedUUIDs, []string{"n5-uuid", "n9-uuid"}, "deletedUUIDs mismatch")
|
||||
|
||||
|
|
@ -2282,13 +2282,13 @@ func TestSendNotes(t *testing.T) {
|
|||
testutils.AssertEqualf(t, noteCount, 7, "note count mismatch")
|
||||
|
||||
var n1, n2, n3, n6, n7, n8, n10 core.Note
|
||||
testutils.MustScan(t, "getting n1", db.QueryRow("SELECT uuid, dirty FROM notes WHERE content = ?", "n1-content"), &n1.UUID, &n1.Dirty)
|
||||
testutils.MustScan(t, "getting n2", db.QueryRow("SELECT uuid, dirty FROM notes WHERE content = ?", "n2-content"), &n2.UUID, &n2.Dirty)
|
||||
testutils.MustScan(t, "getting n3", db.QueryRow("SELECT uuid, dirty FROM notes WHERE content = ?", "n3-content"), &n3.UUID, &n3.Dirty)
|
||||
testutils.MustScan(t, "getting n6", db.QueryRow("SELECT uuid, dirty FROM notes WHERE content = ?", "n6-content"), &n6.UUID, &n6.Dirty)
|
||||
testutils.MustScan(t, "getting n7", db.QueryRow("SELECT uuid, dirty FROM notes WHERE content = ?", "n7-content"), &n7.UUID, &n7.Dirty)
|
||||
testutils.MustScan(t, "getting n8", db.QueryRow("SELECT uuid, dirty FROM notes WHERE content = ?", "n8-content"), &n8.UUID, &n8.Dirty)
|
||||
testutils.MustScan(t, "getting n10", db.QueryRow("SELECT uuid, dirty FROM notes WHERE content = ?", "n10-content"), &n10.UUID, &n10.Dirty)
|
||||
testutils.MustScan(t, "getting n1", db.QueryRow("SELECT uuid, dirty FROM notes WHERE body = ?", "n1-body"), &n1.UUID, &n1.Dirty)
|
||||
testutils.MustScan(t, "getting n2", db.QueryRow("SELECT uuid, dirty FROM notes WHERE body = ?", "n2-body"), &n2.UUID, &n2.Dirty)
|
||||
testutils.MustScan(t, "getting n3", db.QueryRow("SELECT uuid, dirty FROM notes WHERE body = ?", "n3-body"), &n3.UUID, &n3.Dirty)
|
||||
testutils.MustScan(t, "getting n6", db.QueryRow("SELECT uuid, dirty FROM notes WHERE body = ?", "n6-body"), &n6.UUID, &n6.Dirty)
|
||||
testutils.MustScan(t, "getting n7", db.QueryRow("SELECT uuid, dirty FROM notes WHERE body = ?", "n7-body"), &n7.UUID, &n7.Dirty)
|
||||
testutils.MustScan(t, "getting n8", db.QueryRow("SELECT uuid, dirty FROM notes WHERE body = ?", "n8-body"), &n8.UUID, &n8.Dirty)
|
||||
testutils.MustScan(t, "getting n10", db.QueryRow("SELECT uuid, dirty FROM notes WHERE body = ?", "n10-body"), &n10.UUID, &n10.Dirty)
|
||||
|
||||
testutils.AssertEqualf(t, noteCount, 7, "note count mismatch")
|
||||
|
||||
|
|
@ -2302,12 +2302,12 @@ func TestSendNotes(t *testing.T) {
|
|||
|
||||
// UUIDs of created notes should have been updated with those from the server response
|
||||
testutils.AssertEqual(t, n1.UUID, "n1-uuid", "n1 UUID mismatch")
|
||||
testutils.AssertEqual(t, n2.UUID, "server-n2-content-uuid", "n2 UUID mismatch")
|
||||
testutils.AssertEqual(t, n2.UUID, "server-n2-body-uuid", "n2 UUID mismatch")
|
||||
testutils.AssertEqual(t, n3.UUID, "n3-uuid", "n3 UUID mismatch")
|
||||
testutils.AssertEqual(t, n6.UUID, "server-n6-content-uuid", "n6 UUID mismatch")
|
||||
testutils.AssertEqual(t, n6.UUID, "server-n6-body-uuid", "n6 UUID mismatch")
|
||||
testutils.AssertEqual(t, n7.UUID, "n7-uuid", "n7 UUID mismatch")
|
||||
testutils.AssertEqual(t, n8.UUID, "n8-uuid", "n8 UUID mismatch")
|
||||
testutils.AssertEqual(t, n10.UUID, "server-n10-content-uuid", "n10 UUID mismatch")
|
||||
testutils.AssertEqual(t, n10.UUID, "server-n10-body-uuid", "n10 UUID mismatch")
|
||||
}
|
||||
|
||||
func TestSendNotes_isBehind(t *testing.T) {
|
||||
|
|
@ -2327,7 +2327,7 @@ func TestSendNotes_isBehind(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Header().Set("Body-Type", "application/json")
|
||||
if err := json.NewEncoder(w).Encode(resp); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
|
|
@ -2344,7 +2344,7 @@ func TestSendNotes_isBehind(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Header().Set("Body-Type", "application/json")
|
||||
if err := json.NewEncoder(w).Encode(resp); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
|
|
@ -2357,7 +2357,7 @@ func TestSendNotes_isBehind(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Header().Set("Body-Type", "application/json")
|
||||
if err := json.NewEncoder(w).Encode(resp); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
|
|
@ -2396,7 +2396,7 @@ func TestSendNotes_isBehind(t *testing.T) {
|
|||
|
||||
testutils.MustExec(t, fmt.Sprintf("inserting last max usn for test case %d", idx), db, "INSERT INTO system (key, value) VALUES (?, ?)", infra.SystemLastMaxUSN, tc.systemLastMaxUSN)
|
||||
testutils.MustExec(t, "inserting b1", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b1-uuid", "b1-label", 1, false, false)
|
||||
testutils.MustExec(t, "inserting n1", db, "INSERT INTO notes (uuid, book_uuid, usn, content, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", "b1-uuid", 1, "n1 content", 1541108743, false, true)
|
||||
testutils.MustExec(t, "inserting n1", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", "b1-uuid", 1, "n1 body", 1541108743, false, true)
|
||||
|
||||
// execute
|
||||
tx, err := db.Begin()
|
||||
|
|
@ -2444,7 +2444,7 @@ func TestSendNotes_isBehind(t *testing.T) {
|
|||
|
||||
testutils.MustExec(t, fmt.Sprintf("inserting last max usn for test case %d", idx), db, "INSERT INTO system (key, value) VALUES (?, ?)", infra.SystemLastMaxUSN, tc.systemLastMaxUSN)
|
||||
testutils.MustExec(t, "inserting b1", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b1-uuid", "b1-label", 1, false, false)
|
||||
testutils.MustExec(t, "inserting n1", db, "INSERT INTO notes (uuid, book_uuid, usn, content, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", "b1-uuid", 2, "n1 content", 1541108743, true, true)
|
||||
testutils.MustExec(t, "inserting n1", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", "b1-uuid", 2, "n1 body", 1541108743, true, true)
|
||||
|
||||
// execute
|
||||
tx, err := db.Begin()
|
||||
|
|
@ -2492,7 +2492,7 @@ func TestSendNotes_isBehind(t *testing.T) {
|
|||
|
||||
testutils.MustExec(t, fmt.Sprintf("inserting last max usn for test case %d", idx), db, "INSERT INTO system (key, value) VALUES (?, ?)", infra.SystemLastMaxUSN, tc.systemLastMaxUSN)
|
||||
testutils.MustExec(t, "inserting b1", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b1-uuid", "b1-label", 1, false, false)
|
||||
testutils.MustExec(t, "inserting n1", db, "INSERT INTO notes (uuid, book_uuid, usn, content, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", "b1-uuid", 8, "n1 content", 1541108743, false, true)
|
||||
testutils.MustExec(t, "inserting n1", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", "b1-uuid", 8, "n1 body", 1541108743, false, true)
|
||||
|
||||
// execute
|
||||
tx, err := db.Begin()
|
||||
|
|
@ -2523,21 +2523,21 @@ func TestMergeNote(t *testing.T) {
|
|||
addedOn int64
|
||||
clientUSN int
|
||||
clientEditedOn int64
|
||||
clientContent string
|
||||
clientBody string
|
||||
clientPublic bool
|
||||
clientDeleted bool
|
||||
clientBookUUID string
|
||||
clientDirty bool
|
||||
serverUSN int
|
||||
serverEditedOn int64
|
||||
serverContent string
|
||||
serverBody string
|
||||
serverPublic bool
|
||||
serverDeleted bool
|
||||
serverBookUUID string
|
||||
expectedUSN int
|
||||
expectedAddedOn int64
|
||||
expectedEditedOn int64
|
||||
expectedContent string
|
||||
expectedBody string
|
||||
expectedPublic bool
|
||||
expectedDeleted bool
|
||||
expectedBookUUID string
|
||||
|
|
@ -2547,21 +2547,21 @@ func TestMergeNote(t *testing.T) {
|
|||
clientDirty: false,
|
||||
clientUSN: 1,
|
||||
clientEditedOn: 0,
|
||||
clientContent: "n1 content",
|
||||
clientBody: "n1 body",
|
||||
clientPublic: false,
|
||||
clientDeleted: false,
|
||||
clientBookUUID: b1UUID,
|
||||
addedOn: 1541232118,
|
||||
serverUSN: 21,
|
||||
serverEditedOn: 1541219321,
|
||||
serverContent: "n1 content edited",
|
||||
serverBody: "n1 body edited",
|
||||
serverPublic: true,
|
||||
serverDeleted: false,
|
||||
serverBookUUID: b2UUID,
|
||||
expectedUSN: 21,
|
||||
expectedAddedOn: 1541232118,
|
||||
expectedEditedOn: 1541219321,
|
||||
expectedContent: "n1 content edited",
|
||||
expectedBody: "n1 body edited",
|
||||
expectedPublic: true,
|
||||
expectedDeleted: false,
|
||||
expectedBookUUID: b2UUID,
|
||||
|
|
@ -2572,21 +2572,21 @@ func TestMergeNote(t *testing.T) {
|
|||
clientDirty: true,
|
||||
clientUSN: 1,
|
||||
clientEditedOn: 1541219321,
|
||||
clientContent: "",
|
||||
clientBody: "",
|
||||
clientPublic: false,
|
||||
clientDeleted: true,
|
||||
clientBookUUID: b1UUID,
|
||||
addedOn: 1541232118,
|
||||
serverUSN: 21,
|
||||
serverEditedOn: 1541219321,
|
||||
serverContent: "n1 content edited",
|
||||
serverBody: "n1 body edited",
|
||||
serverPublic: false,
|
||||
serverDeleted: false,
|
||||
serverBookUUID: b2UUID,
|
||||
expectedUSN: 21,
|
||||
expectedAddedOn: 1541232118,
|
||||
expectedEditedOn: 1541219321,
|
||||
expectedContent: "n1 content edited",
|
||||
expectedBody: "n1 body edited",
|
||||
expectedPublic: false,
|
||||
expectedDeleted: false,
|
||||
expectedBookUUID: b2UUID,
|
||||
|
|
@ -2605,7 +2605,7 @@ func TestMergeNote(t *testing.T) {
|
|||
testutils.MustExec(t, fmt.Sprintf("inserting b1 for test case %d", idx), db, "INSERT INTO books (uuid, label, usn, dirty) VALUES (?, ?, ?, ?)", b1UUID, "b1-label", 5, false)
|
||||
testutils.MustExec(t, fmt.Sprintf("inserting b2 for test case %d", idx), db, "INSERT INTO books (uuid, label, usn, dirty) VALUES (?, ?, ?, ?)", b2UUID, "b2-label", 6, false)
|
||||
n1UUID := utils.GenerateUUID()
|
||||
testutils.MustExec(t, fmt.Sprintf("inserting n1 for test case %d", idx), db, "INSERT INTO notes (uuid, book_uuid, usn, added_on, edited_on, content, public, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", n1UUID, b1UUID, tc.clientUSN, tc.addedOn, tc.clientEditedOn, tc.clientContent, tc.clientPublic, tc.clientDeleted, tc.clientDirty)
|
||||
testutils.MustExec(t, fmt.Sprintf("inserting n1 for test case %d", idx), db, "INSERT INTO notes (uuid, book_uuid, usn, added_on, edited_on, body, public, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", n1UUID, b1UUID, tc.clientUSN, tc.addedOn, tc.clientEditedOn, tc.clientBody, tc.clientPublic, tc.clientDeleted, tc.clientDirty)
|
||||
|
||||
// execute
|
||||
tx, err := db.Begin()
|
||||
|
|
@ -2620,14 +2620,14 @@ func TestMergeNote(t *testing.T) {
|
|||
USN: tc.serverUSN,
|
||||
AddedOn: tc.addedOn,
|
||||
EditedOn: tc.serverEditedOn,
|
||||
Content: tc.serverContent,
|
||||
Body: tc.serverBody,
|
||||
Public: tc.serverPublic,
|
||||
Deleted: tc.serverDeleted,
|
||||
}
|
||||
var localNote core.Note
|
||||
testutils.MustScan(t, fmt.Sprintf("getting localNote for test case %d", idx),
|
||||
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, content, public, deleted, dirty FROM notes WHERE uuid = ?", n1UUID),
|
||||
&localNote.UUID, &localNote.BookUUID, &localNote.USN, &localNote.AddedOn, &localNote.EditedOn, &localNote.Content, &localNote.Public, &localNote.Deleted, &localNote.Dirty)
|
||||
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, body, public, deleted, dirty FROM notes WHERE uuid = ?", n1UUID),
|
||||
&localNote.UUID, &localNote.BookUUID, &localNote.USN, &localNote.AddedOn, &localNote.EditedOn, &localNote.Body, &localNote.Public, &localNote.Deleted, &localNote.Dirty)
|
||||
|
||||
if err := mergeNote(tx, fragNote, localNote); err != nil {
|
||||
tx.Rollback()
|
||||
|
|
@ -2646,8 +2646,8 @@ func TestMergeNote(t *testing.T) {
|
|||
|
||||
var n1Record core.Note
|
||||
testutils.MustScan(t, fmt.Sprintf("getting n1Record for test case %d", idx),
|
||||
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, content, public, deleted, dirty FROM notes WHERE uuid = ?", n1UUID),
|
||||
&n1Record.UUID, &n1Record.BookUUID, &n1Record.USN, &n1Record.AddedOn, &n1Record.EditedOn, &n1Record.Content, &n1Record.Public, &n1Record.Deleted, &n1Record.Dirty)
|
||||
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, body, public, deleted, dirty FROM notes WHERE uuid = ?", n1UUID),
|
||||
&n1Record.UUID, &n1Record.BookUUID, &n1Record.USN, &n1Record.AddedOn, &n1Record.EditedOn, &n1Record.Body, &n1Record.Public, &n1Record.Deleted, &n1Record.Dirty)
|
||||
var b1Record core.Book
|
||||
testutils.MustScan(t, "getting b1Record for test case",
|
||||
db.QueryRow("SELECT uuid, label, usn, dirty FROM books WHERE uuid = ?", b1UUID),
|
||||
|
|
@ -2672,7 +2672,7 @@ func TestMergeNote(t *testing.T) {
|
|||
testutils.AssertEqual(t, n1Record.USN, tc.expectedUSN, fmt.Sprintf("n1Record USN mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, n1Record.AddedOn, tc.expectedAddedOn, fmt.Sprintf("n1Record AddedOn mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, n1Record.EditedOn, tc.expectedEditedOn, fmt.Sprintf("n1Record EditedOn mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, n1Record.Content, tc.expectedContent, fmt.Sprintf("n1Record Content mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, n1Record.Body, tc.expectedBody, fmt.Sprintf("n1Record Body mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, n1Record.Public, tc.expectedPublic, fmt.Sprintf("n1Record Public mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, n1Record.Deleted, tc.expectedDeleted, fmt.Sprintf("n1Record Deleted mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, n1Record.Dirty, tc.expectedDirty, fmt.Sprintf("n1Record Dirty mismatch for test case %d", idx))
|
||||
|
|
@ -2689,11 +2689,11 @@ func TestCheckBookPristine(t *testing.T) {
|
|||
|
||||
testutils.MustExec(t, "inserting b1", db, "INSERT INTO books (uuid, label, usn, dirty) VALUES (?, ?, ?, ?)", "b1-uuid", "b1-label", 5, false)
|
||||
testutils.MustExec(t, "inserting b2", db, "INSERT INTO books (uuid, label, usn, dirty) VALUES (?, ?, ?, ?)", "b2-uuid", "b2-label", 6, false)
|
||||
testutils.MustExec(t, "inserting n1", db, "INSERT INTO notes (uuid, book_uuid, added_on, content, dirty) VALUES (?, ?, ?, ?, ?)", "n1-uuid", "b1-uuid", 1541108743, "n1 content", false)
|
||||
testutils.MustExec(t, "inserting n2", db, "INSERT INTO notes (uuid, book_uuid, added_on, content, dirty) VALUES (?, ?, ?, ?, ?)", "n2-uuid", "b1-uuid", 1541108743, "n2 content", false)
|
||||
testutils.MustExec(t, "inserting n3", db, "INSERT INTO notes (uuid, book_uuid, added_on, content, dirty) VALUES (?, ?, ?, ?, ?)", "n3-uuid", "b1-uuid", 1541108743, "n3 content", true)
|
||||
testutils.MustExec(t, "inserting n4", db, "INSERT INTO notes (uuid, book_uuid, added_on, content, dirty) VALUES (?, ?, ?, ?, ?)", "n4-uuid", "b2-uuid", 1541108743, "n4 content", false)
|
||||
testutils.MustExec(t, "inserting n5", db, "INSERT INTO notes (uuid, book_uuid, added_on, content, dirty) VALUES (?, ?, ?, ?, ?)", "n5-uuid", "b2-uuid", 1541108743, "n5 content", false)
|
||||
testutils.MustExec(t, "inserting n1", db, "INSERT INTO notes (uuid, book_uuid, added_on, body, dirty) VALUES (?, ?, ?, ?, ?)", "n1-uuid", "b1-uuid", 1541108743, "n1 body", false)
|
||||
testutils.MustExec(t, "inserting n2", db, "INSERT INTO notes (uuid, book_uuid, added_on, body, dirty) VALUES (?, ?, ?, ?, ?)", "n2-uuid", "b1-uuid", 1541108743, "n2 body", false)
|
||||
testutils.MustExec(t, "inserting n3", db, "INSERT INTO notes (uuid, book_uuid, added_on, body, dirty) VALUES (?, ?, ?, ?, ?)", "n3-uuid", "b1-uuid", 1541108743, "n3 body", true)
|
||||
testutils.MustExec(t, "inserting n4", db, "INSERT INTO notes (uuid, book_uuid, added_on, body, dirty) VALUES (?, ?, ?, ?, ?)", "n4-uuid", "b2-uuid", 1541108743, "n4 body", false)
|
||||
testutils.MustExec(t, "inserting n5", db, "INSERT INTO notes (uuid, book_uuid, added_on, body, dirty) VALUES (?, ?, ?, ?, ?)", "n5-uuid", "b2-uuid", 1541108743, "n5 body", false)
|
||||
|
||||
t.Run("b1", func(t *testing.T) {
|
||||
// execute
|
||||
|
|
@ -2896,15 +2896,15 @@ func TestCleanLocalNotes(t *testing.T) {
|
|||
testutils.MustExec(t, "inserting b1", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", b1UUID, "b1-label", 1, false, false)
|
||||
|
||||
// exists in the list
|
||||
testutils.MustExec(t, "inserting n1", db, "INSERT INTO notes (uuid, book_uuid, usn, content, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", b1UUID, 10, "n1 content", 1541108743, false, false)
|
||||
testutils.MustExec(t, "inserting n2", db, "INSERT INTO notes (uuid, book_uuid, usn, content, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n2-uuid", b1UUID, 0, "n2 content", 1541108743, false, true)
|
||||
testutils.MustExec(t, "inserting n1", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", b1UUID, 10, "n1 body", 1541108743, false, false)
|
||||
testutils.MustExec(t, "inserting n2", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n2-uuid", b1UUID, 0, "n2 body", 1541108743, false, true)
|
||||
// non-existent in the list but in valid state
|
||||
// (created in the cli and hasn't been uploaded)
|
||||
testutils.MustExec(t, "inserting n6", db, "INSERT INTO notes (uuid, book_uuid, usn, content, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n6-uuid", b1UUID, 0, "n6 content", 1541108743, false, true)
|
||||
testutils.MustExec(t, "inserting n6", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n6-uuid", b1UUID, 0, "n6 body", 1541108743, false, true)
|
||||
// non-existent in the list and in an invalid state
|
||||
testutils.MustExec(t, "inserting n5", db, "INSERT INTO notes (uuid, book_uuid, usn, content, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n5-uuid", b1UUID, 7, "n5 content", 1541108743, true, true)
|
||||
testutils.MustExec(t, "inserting n9", db, "INSERT INTO notes (uuid, book_uuid, usn, content, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n9-uuid", b1UUID, 17, "n9 content", 1541108743, true, false)
|
||||
testutils.MustExec(t, "inserting n10", db, "INSERT INTO notes (uuid, book_uuid, usn, content, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n10-uuid", b1UUID, 0, "n10 content", 1541108743, false, false)
|
||||
testutils.MustExec(t, "inserting n5", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n5-uuid", b1UUID, 7, "n5 body", 1541108743, true, true)
|
||||
testutils.MustExec(t, "inserting n9", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n9-uuid", b1UUID, 17, "n9 body", 1541108743, true, false)
|
||||
testutils.MustExec(t, "inserting n10", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n10-uuid", b1UUID, 0, "n10 body", 1541108743, false, false)
|
||||
|
||||
// execute
|
||||
tx, err := db.Begin()
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ type Book struct {
|
|||
type Note struct {
|
||||
UUID string `json:"uuid"`
|
||||
BookUUID string `json:"book_uuid"`
|
||||
Content string `json:"content"`
|
||||
Body string `json:"content"`
|
||||
AddedOn int64 `json:"added_on"`
|
||||
EditedOn int64 `json:"edited_on"`
|
||||
USN int `json:"usn"`
|
||||
|
|
@ -30,11 +30,11 @@ type Note struct {
|
|||
}
|
||||
|
||||
// NewNote constructs a note with the given data
|
||||
func NewNote(uuid, bookUUID, content string, addedOn, editedOn int64, usn int, public, deleted, dirty bool) Note {
|
||||
func NewNote(uuid, bookUUID, body string, addedOn, editedOn int64, usn int, public, deleted, dirty bool) Note {
|
||||
return Note{
|
||||
UUID: uuid,
|
||||
BookUUID: bookUUID,
|
||||
Content: content,
|
||||
Body: body,
|
||||
AddedOn: addedOn,
|
||||
EditedOn: editedOn,
|
||||
USN: usn,
|
||||
|
|
@ -46,8 +46,8 @@ func NewNote(uuid, bookUUID, content string, addedOn, editedOn int64, usn int, p
|
|||
|
||||
// Insert inserts a new note
|
||||
func (n Note) Insert(tx *sql.Tx) error {
|
||||
_, err := tx.Exec("INSERT INTO notes (uuid, book_uuid, content, added_on, edited_on, usn, public, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||
n.UUID, n.BookUUID, n.Content, n.AddedOn, n.EditedOn, n.USN, n.Public, n.Deleted, n.Dirty)
|
||||
_, err := tx.Exec("INSERT INTO notes (uuid, book_uuid, body, added_on, edited_on, usn, public, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||
n.UUID, n.BookUUID, n.Body, n.AddedOn, n.EditedOn, n.USN, n.Public, n.Deleted, n.Dirty)
|
||||
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "inserting note with uuid %s", n.UUID)
|
||||
|
|
@ -58,8 +58,8 @@ func (n Note) Insert(tx *sql.Tx) error {
|
|||
|
||||
// Update updates the note with the given data
|
||||
func (n Note) Update(tx *sql.Tx) error {
|
||||
_, err := tx.Exec("UPDATE notes SET book_uuid = ?, content = ?, added_on = ?, edited_on = ?, usn = ?, public = ?, deleted = ?, dirty = ? WHERE uuid = ?",
|
||||
n.BookUUID, n.Content, n.AddedOn, n.EditedOn, n.USN, n.Public, n.Deleted, n.Dirty, n.UUID)
|
||||
_, err := tx.Exec("UPDATE notes SET book_uuid = ?, body = ?, added_on = ?, edited_on = ?, usn = ?, public = ?, deleted = ?, dirty = ? WHERE uuid = ?",
|
||||
n.BookUUID, n.Body, n.AddedOn, n.EditedOn, n.USN, n.Public, n.Deleted, n.Dirty, n.UUID)
|
||||
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "updating the note with uuid %s", n.UUID)
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ func TestNewNote(t *testing.T) {
|
|||
testCases := []struct {
|
||||
uuid string
|
||||
bookUUID string
|
||||
content string
|
||||
body string
|
||||
addedOn int64
|
||||
editedOn int64
|
||||
usn int
|
||||
|
|
@ -23,7 +23,7 @@ func TestNewNote(t *testing.T) {
|
|||
{
|
||||
uuid: "n1-uuid",
|
||||
bookUUID: "b1-uuid",
|
||||
content: "n1-content",
|
||||
body: "n1-body",
|
||||
addedOn: 1542058875,
|
||||
editedOn: 0,
|
||||
usn: 0,
|
||||
|
|
@ -34,7 +34,7 @@ func TestNewNote(t *testing.T) {
|
|||
{
|
||||
uuid: "n2-uuid",
|
||||
bookUUID: "b2-uuid",
|
||||
content: "n2-content",
|
||||
body: "n2-body",
|
||||
addedOn: 1542058875,
|
||||
editedOn: 1542058876,
|
||||
usn: 1008,
|
||||
|
|
@ -45,11 +45,11 @@ func TestNewNote(t *testing.T) {
|
|||
}
|
||||
|
||||
for idx, tc := range testCases {
|
||||
got := NewNote(tc.uuid, tc.bookUUID, tc.content, tc.addedOn, tc.editedOn, tc.usn, tc.public, tc.deleted, tc.dirty)
|
||||
got := NewNote(tc.uuid, tc.bookUUID, tc.body, tc.addedOn, tc.editedOn, tc.usn, tc.public, tc.deleted, tc.dirty)
|
||||
|
||||
testutils.AssertEqual(t, got.UUID, tc.uuid, fmt.Sprintf("UUID mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, got.BookUUID, tc.bookUUID, fmt.Sprintf("BookUUID mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, got.Content, tc.content, fmt.Sprintf("Content mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, got.Body, tc.body, fmt.Sprintf("Body mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, got.AddedOn, tc.addedOn, fmt.Sprintf("AddedOn mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, got.EditedOn, tc.editedOn, fmt.Sprintf("EditedOn mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, got.USN, tc.usn, fmt.Sprintf("USN mismatch for test case %d", idx))
|
||||
|
|
@ -63,7 +63,7 @@ func TestNoteInsert(t *testing.T) {
|
|||
testCases := []struct {
|
||||
uuid string
|
||||
bookUUID string
|
||||
content string
|
||||
body string
|
||||
addedOn int64
|
||||
editedOn int64
|
||||
usn int
|
||||
|
|
@ -74,7 +74,7 @@ func TestNoteInsert(t *testing.T) {
|
|||
{
|
||||
uuid: "n1-uuid",
|
||||
bookUUID: "b1-uuid",
|
||||
content: "n1-content",
|
||||
body: "n1-body",
|
||||
addedOn: 1542058875,
|
||||
editedOn: 0,
|
||||
usn: 0,
|
||||
|
|
@ -85,7 +85,7 @@ func TestNoteInsert(t *testing.T) {
|
|||
{
|
||||
uuid: "n2-uuid",
|
||||
bookUUID: "b2-uuid",
|
||||
content: "n2-content",
|
||||
body: "n2-body",
|
||||
addedOn: 1542058875,
|
||||
editedOn: 1542058876,
|
||||
usn: 1008,
|
||||
|
|
@ -104,7 +104,7 @@ func TestNoteInsert(t *testing.T) {
|
|||
n := Note{
|
||||
UUID: tc.uuid,
|
||||
BookUUID: tc.bookUUID,
|
||||
Content: tc.content,
|
||||
Body: tc.body,
|
||||
AddedOn: tc.addedOn,
|
||||
EditedOn: tc.editedOn,
|
||||
USN: tc.usn,
|
||||
|
|
@ -129,17 +129,17 @@ func TestNoteInsert(t *testing.T) {
|
|||
tx.Commit()
|
||||
|
||||
// test
|
||||
var uuid, bookUUID, content string
|
||||
var uuid, bookUUID, body string
|
||||
var addedOn, editedOn int64
|
||||
var usn int
|
||||
var public, deleted, dirty bool
|
||||
testutils.MustScan(t, "getting n1",
|
||||
db.QueryRow("SELECT uuid, book_uuid, content, added_on, edited_on, usn, public, deleted, dirty FROM notes WHERE uuid = ?", tc.uuid),
|
||||
&uuid, &bookUUID, &content, &addedOn, &editedOn, &usn, &public, &deleted, &dirty)
|
||||
db.QueryRow("SELECT uuid, book_uuid, body, added_on, edited_on, usn, public, deleted, dirty FROM notes WHERE uuid = ?", tc.uuid),
|
||||
&uuid, &bookUUID, &body, &addedOn, &editedOn, &usn, &public, &deleted, &dirty)
|
||||
|
||||
testutils.AssertEqual(t, uuid, tc.uuid, fmt.Sprintf("uuid mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, bookUUID, tc.bookUUID, fmt.Sprintf("bookUUID mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, content, tc.content, fmt.Sprintf("content mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, body, tc.body, fmt.Sprintf("body mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, addedOn, tc.addedOn, fmt.Sprintf("addedOn mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, editedOn, tc.editedOn, fmt.Sprintf("editedOn mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, usn, tc.usn, fmt.Sprintf("usn mismatch for test case %d", idx))
|
||||
|
|
@ -154,7 +154,7 @@ func TestNoteUpdate(t *testing.T) {
|
|||
testCases := []struct {
|
||||
uuid string
|
||||
bookUUID string
|
||||
content string
|
||||
body string
|
||||
addedOn int64
|
||||
editedOn int64
|
||||
usn int
|
||||
|
|
@ -162,7 +162,7 @@ func TestNoteUpdate(t *testing.T) {
|
|||
deleted bool
|
||||
dirty bool
|
||||
newBookUUID string
|
||||
newContent string
|
||||
newBody string
|
||||
newEditedOn int64
|
||||
newUSN int
|
||||
newPublic bool
|
||||
|
|
@ -172,7 +172,7 @@ func TestNoteUpdate(t *testing.T) {
|
|||
{
|
||||
uuid: "n1-uuid",
|
||||
bookUUID: "b1-uuid",
|
||||
content: "n1-content",
|
||||
body: "n1-body",
|
||||
addedOn: 1542058875,
|
||||
editedOn: 0,
|
||||
usn: 0,
|
||||
|
|
@ -180,7 +180,7 @@ func TestNoteUpdate(t *testing.T) {
|
|||
deleted: false,
|
||||
dirty: false,
|
||||
newBookUUID: "b1-uuid",
|
||||
newContent: "n1-content edited",
|
||||
newBody: "n1-body edited",
|
||||
newEditedOn: 1542058879,
|
||||
newUSN: 0,
|
||||
newPublic: false,
|
||||
|
|
@ -190,7 +190,7 @@ func TestNoteUpdate(t *testing.T) {
|
|||
{
|
||||
uuid: "n1-uuid",
|
||||
bookUUID: "b1-uuid",
|
||||
content: "n1-content",
|
||||
body: "n1-body",
|
||||
addedOn: 1542058875,
|
||||
editedOn: 0,
|
||||
usn: 0,
|
||||
|
|
@ -198,7 +198,7 @@ func TestNoteUpdate(t *testing.T) {
|
|||
deleted: false,
|
||||
dirty: true,
|
||||
newBookUUID: "b2-uuid",
|
||||
newContent: "n1-content",
|
||||
newBody: "n1-body",
|
||||
newEditedOn: 1542058879,
|
||||
newUSN: 0,
|
||||
newPublic: true,
|
||||
|
|
@ -208,7 +208,7 @@ func TestNoteUpdate(t *testing.T) {
|
|||
{
|
||||
uuid: "n1-uuid",
|
||||
bookUUID: "b1-uuid",
|
||||
content: "n1-content",
|
||||
body: "n1-body",
|
||||
addedOn: 1542058875,
|
||||
editedOn: 0,
|
||||
usn: 10,
|
||||
|
|
@ -216,7 +216,7 @@ func TestNoteUpdate(t *testing.T) {
|
|||
deleted: false,
|
||||
dirty: false,
|
||||
newBookUUID: "",
|
||||
newContent: "",
|
||||
newBody: "",
|
||||
newEditedOn: 1542058879,
|
||||
newUSN: 151,
|
||||
newPublic: false,
|
||||
|
|
@ -226,7 +226,7 @@ func TestNoteUpdate(t *testing.T) {
|
|||
{
|
||||
uuid: "n1-uuid",
|
||||
bookUUID: "b1-uuid",
|
||||
content: "n1-content",
|
||||
body: "n1-body",
|
||||
addedOn: 1542058875,
|
||||
editedOn: 0,
|
||||
usn: 0,
|
||||
|
|
@ -234,7 +234,7 @@ func TestNoteUpdate(t *testing.T) {
|
|||
deleted: false,
|
||||
dirty: false,
|
||||
newBookUUID: "",
|
||||
newContent: "",
|
||||
newBody: "",
|
||||
newEditedOn: 1542058879,
|
||||
newUSN: 15,
|
||||
newPublic: false,
|
||||
|
|
@ -252,7 +252,7 @@ func TestNoteUpdate(t *testing.T) {
|
|||
n1 := Note{
|
||||
UUID: tc.uuid,
|
||||
BookUUID: tc.bookUUID,
|
||||
Content: tc.content,
|
||||
Body: tc.body,
|
||||
AddedOn: tc.addedOn,
|
||||
EditedOn: tc.editedOn,
|
||||
USN: tc.usn,
|
||||
|
|
@ -263,7 +263,7 @@ func TestNoteUpdate(t *testing.T) {
|
|||
n2 := Note{
|
||||
UUID: "n2-uuid",
|
||||
BookUUID: "b10-uuid",
|
||||
Content: "n2 content",
|
||||
Body: "n2 body",
|
||||
AddedOn: 1542058875,
|
||||
EditedOn: 0,
|
||||
USN: 39,
|
||||
|
|
@ -273,8 +273,8 @@ func TestNoteUpdate(t *testing.T) {
|
|||
}
|
||||
|
||||
db := ctx.DB
|
||||
testutils.MustExec(t, fmt.Sprintf("inserting n1 for test case %d", idx), db, "INSERT INTO notes (uuid, book_uuid, usn, added_on, edited_on, content, public, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", n1.UUID, n1.BookUUID, n1.USN, n1.AddedOn, n1.EditedOn, n1.Content, n1.Public, n1.Deleted, n1.Dirty)
|
||||
testutils.MustExec(t, fmt.Sprintf("inserting n2 for test case %d", idx), db, "INSERT INTO notes (uuid, book_uuid, usn, added_on, edited_on, content, public, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", n2.UUID, n2.BookUUID, n2.USN, n2.AddedOn, n2.EditedOn, n2.Content, n2.Public, n2.Deleted, n2.Dirty)
|
||||
testutils.MustExec(t, fmt.Sprintf("inserting n1 for test case %d", idx), db, "INSERT INTO notes (uuid, book_uuid, usn, added_on, edited_on, body, public, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", n1.UUID, n1.BookUUID, n1.USN, n1.AddedOn, n1.EditedOn, n1.Body, n1.Public, n1.Deleted, n1.Dirty)
|
||||
testutils.MustExec(t, fmt.Sprintf("inserting n2 for test case %d", idx), db, "INSERT INTO notes (uuid, book_uuid, usn, added_on, edited_on, body, public, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", n2.UUID, n2.BookUUID, n2.USN, n2.AddedOn, n2.EditedOn, n2.Body, n2.Public, n2.Deleted, n2.Dirty)
|
||||
|
||||
// execute
|
||||
tx, err := db.Begin()
|
||||
|
|
@ -283,7 +283,7 @@ func TestNoteUpdate(t *testing.T) {
|
|||
}
|
||||
|
||||
n1.BookUUID = tc.newBookUUID
|
||||
n1.Content = tc.newContent
|
||||
n1.Body = tc.newBody
|
||||
n1.EditedOn = tc.newEditedOn
|
||||
n1.USN = tc.newUSN
|
||||
n1.Public = tc.newPublic
|
||||
|
|
@ -300,15 +300,15 @@ func TestNoteUpdate(t *testing.T) {
|
|||
// test
|
||||
var n1Record, n2Record Note
|
||||
testutils.MustScan(t, "getting n1",
|
||||
db.QueryRow("SELECT uuid, book_uuid, content, added_on, edited_on, usn, public, deleted, dirty FROM notes WHERE uuid = ?", tc.uuid),
|
||||
&n1Record.UUID, &n1Record.BookUUID, &n1Record.Content, &n1Record.AddedOn, &n1Record.EditedOn, &n1Record.USN, &n1Record.Public, &n1Record.Deleted, &n1Record.Dirty)
|
||||
db.QueryRow("SELECT uuid, book_uuid, body, added_on, edited_on, usn, public, deleted, dirty FROM notes WHERE uuid = ?", tc.uuid),
|
||||
&n1Record.UUID, &n1Record.BookUUID, &n1Record.Body, &n1Record.AddedOn, &n1Record.EditedOn, &n1Record.USN, &n1Record.Public, &n1Record.Deleted, &n1Record.Dirty)
|
||||
testutils.MustScan(t, "getting n2",
|
||||
db.QueryRow("SELECT uuid, book_uuid, content, added_on, edited_on, usn, public, deleted, dirty FROM notes WHERE uuid = ?", n2.UUID),
|
||||
&n2Record.UUID, &n2Record.BookUUID, &n2Record.Content, &n2Record.AddedOn, &n2Record.EditedOn, &n2Record.USN, &n2Record.Public, &n2Record.Deleted, &n2Record.Dirty)
|
||||
db.QueryRow("SELECT uuid, book_uuid, body, added_on, edited_on, usn, public, deleted, dirty FROM notes WHERE uuid = ?", n2.UUID),
|
||||
&n2Record.UUID, &n2Record.BookUUID, &n2Record.Body, &n2Record.AddedOn, &n2Record.EditedOn, &n2Record.USN, &n2Record.Public, &n2Record.Deleted, &n2Record.Dirty)
|
||||
|
||||
testutils.AssertEqual(t, n1Record.UUID, n1.UUID, fmt.Sprintf("n1 uuid mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, n1Record.BookUUID, tc.newBookUUID, fmt.Sprintf("n1 bookUUID mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, n1Record.Content, tc.newContent, fmt.Sprintf("n1 content mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, n1Record.Body, tc.newBody, fmt.Sprintf("n1 body mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, n1Record.AddedOn, n1.AddedOn, fmt.Sprintf("n1 addedOn mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, n1Record.EditedOn, tc.newEditedOn, fmt.Sprintf("n1 editedOn mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, n1Record.USN, tc.newUSN, fmt.Sprintf("n1 usn mismatch for test case %d", idx))
|
||||
|
|
@ -318,7 +318,7 @@ func TestNoteUpdate(t *testing.T) {
|
|||
|
||||
testutils.AssertEqual(t, n2Record.UUID, n2.UUID, fmt.Sprintf("n2 uuid mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, n2Record.BookUUID, n2.BookUUID, fmt.Sprintf("n2 bookUUID mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, n2Record.Content, n2.Content, fmt.Sprintf("n2 content mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, n2Record.Body, n2.Body, fmt.Sprintf("n2 body mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, n2Record.AddedOn, n2.AddedOn, fmt.Sprintf("n2 addedOn mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, n2Record.EditedOn, n2.EditedOn, fmt.Sprintf("n2 editedOn mismatch for test case %d", idx))
|
||||
testutils.AssertEqual(t, n2Record.USN, n2.USN, fmt.Sprintf("n2 usn mismatch for test case %d", idx))
|
||||
|
|
@ -351,7 +351,7 @@ func TestNoteUpdateUUID(t *testing.T) {
|
|||
UUID: "n1-uuid",
|
||||
BookUUID: "b1-uuid",
|
||||
AddedOn: 1542058874,
|
||||
Content: "n1-content",
|
||||
Body: "n1-body",
|
||||
USN: 1,
|
||||
Deleted: true,
|
||||
Dirty: false,
|
||||
|
|
@ -360,15 +360,15 @@ func TestNoteUpdateUUID(t *testing.T) {
|
|||
UUID: "n2-uuid",
|
||||
BookUUID: "b1-uuid",
|
||||
AddedOn: 1542058874,
|
||||
Content: "n2-content",
|
||||
Body: "n2-body",
|
||||
USN: 1,
|
||||
Deleted: true,
|
||||
Dirty: false,
|
||||
}
|
||||
|
||||
db := ctx.DB
|
||||
testutils.MustExec(t, "inserting n1", db, "INSERT INTO notes (uuid, book_uuid, content, added_on, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", n1.UUID, n1.BookUUID, n1.Content, n1.AddedOn, n1.USN, n1.Deleted, n1.Dirty)
|
||||
testutils.MustExec(t, "inserting n2", db, "INSERT INTO notes (uuid, book_uuid, content, added_on, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", n2.UUID, n2.BookUUID, n2.Content, n2.AddedOn, n2.USN, n2.Deleted, n2.Dirty)
|
||||
testutils.MustExec(t, "inserting n1", db, "INSERT INTO notes (uuid, book_uuid, body, added_on, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", n1.UUID, n1.BookUUID, n1.Body, n1.AddedOn, n1.USN, n1.Deleted, n1.Dirty)
|
||||
testutils.MustExec(t, "inserting n2", db, "INSERT INTO notes (uuid, book_uuid, body, added_on, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", n2.UUID, n2.BookUUID, n2.Body, n2.AddedOn, n2.USN, n2.Deleted, n2.Dirty)
|
||||
|
||||
// execute
|
||||
tx, err := db.Begin()
|
||||
|
|
@ -385,11 +385,11 @@ func TestNoteUpdateUUID(t *testing.T) {
|
|||
// test
|
||||
var n1Record, n2Record Note
|
||||
testutils.MustScan(t, "getting n1",
|
||||
db.QueryRow("SELECT uuid, content, usn, deleted, dirty FROM notes WHERE content = ?", "n1-content"),
|
||||
&n1Record.UUID, &n1Record.Content, &n1Record.USN, &n1Record.Deleted, &n1Record.Dirty)
|
||||
db.QueryRow("SELECT uuid, body, usn, deleted, dirty FROM notes WHERE body = ?", "n1-body"),
|
||||
&n1Record.UUID, &n1Record.Body, &n1Record.USN, &n1Record.Deleted, &n1Record.Dirty)
|
||||
testutils.MustScan(t, "getting n2",
|
||||
db.QueryRow("SELECT uuid, content, usn, deleted, dirty FROM notes WHERE content = ?", "n2-content"),
|
||||
&n2Record.UUID, &n2Record.Content, &n2Record.USN, &n2Record.Deleted, &n2Record.Dirty)
|
||||
db.QueryRow("SELECT uuid, body, usn, deleted, dirty FROM notes WHERE body = ?", "n2-body"),
|
||||
&n2Record.UUID, &n2Record.Body, &n2Record.USN, &n2Record.Deleted, &n2Record.Dirty)
|
||||
|
||||
testutils.AssertEqual(t, n1.UUID, tc.newUUID, "n1 original reference uuid mismatch")
|
||||
testutils.AssertEqual(t, n1Record.UUID, tc.newUUID, "n1 uuid mismatch")
|
||||
|
|
@ -406,7 +406,7 @@ func TestNoteExpunge(t *testing.T) {
|
|||
n1 := Note{
|
||||
UUID: "n1-uuid",
|
||||
BookUUID: "b9-uuid",
|
||||
Content: "n1 content",
|
||||
Body: "n1 body",
|
||||
AddedOn: 1542058874,
|
||||
EditedOn: 0,
|
||||
USN: 22,
|
||||
|
|
@ -417,7 +417,7 @@ func TestNoteExpunge(t *testing.T) {
|
|||
n2 := Note{
|
||||
UUID: "n2-uuid",
|
||||
BookUUID: "b10-uuid",
|
||||
Content: "n2 content",
|
||||
Body: "n2 body",
|
||||
AddedOn: 1542058875,
|
||||
EditedOn: 0,
|
||||
USN: 39,
|
||||
|
|
@ -427,8 +427,8 @@ func TestNoteExpunge(t *testing.T) {
|
|||
}
|
||||
|
||||
db := ctx.DB
|
||||
testutils.MustExec(t, "inserting n1", db, "INSERT INTO notes (uuid, book_uuid, usn, added_on, edited_on, content, public, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", n1.UUID, n1.BookUUID, n1.USN, n1.AddedOn, n1.EditedOn, n1.Content, n1.Public, n1.Deleted, n1.Dirty)
|
||||
testutils.MustExec(t, "inserting n2", db, "INSERT INTO notes (uuid, book_uuid, usn, added_on, edited_on, content, public, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", n2.UUID, n2.BookUUID, n2.USN, n2.AddedOn, n2.EditedOn, n2.Content, n2.Public, n2.Deleted, n2.Dirty)
|
||||
testutils.MustExec(t, "inserting n1", db, "INSERT INTO notes (uuid, book_uuid, usn, added_on, edited_on, body, public, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", n1.UUID, n1.BookUUID, n1.USN, n1.AddedOn, n1.EditedOn, n1.Body, n1.Public, n1.Deleted, n1.Dirty)
|
||||
testutils.MustExec(t, "inserting n2", db, "INSERT INTO notes (uuid, book_uuid, usn, added_on, edited_on, body, public, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", n2.UUID, n2.BookUUID, n2.USN, n2.AddedOn, n2.EditedOn, n2.Body, n2.Public, n2.Deleted, n2.Dirty)
|
||||
|
||||
// execute
|
||||
tx, err := db.Begin()
|
||||
|
|
@ -451,12 +451,12 @@ func TestNoteExpunge(t *testing.T) {
|
|||
|
||||
var n2Record Note
|
||||
testutils.MustScan(t, "getting n2",
|
||||
db.QueryRow("SELECT uuid, book_uuid, content, added_on, edited_on, usn, public, deleted, dirty FROM notes WHERE uuid = ?", n2.UUID),
|
||||
&n2Record.UUID, &n2Record.BookUUID, &n2Record.Content, &n2Record.AddedOn, &n2Record.EditedOn, &n2Record.USN, &n2Record.Public, &n2Record.Deleted, &n2Record.Dirty)
|
||||
db.QueryRow("SELECT uuid, book_uuid, body, added_on, edited_on, usn, public, deleted, dirty FROM notes WHERE uuid = ?", n2.UUID),
|
||||
&n2Record.UUID, &n2Record.BookUUID, &n2Record.Body, &n2Record.AddedOn, &n2Record.EditedOn, &n2Record.USN, &n2Record.Public, &n2Record.Deleted, &n2Record.Dirty)
|
||||
|
||||
testutils.AssertEqual(t, n2Record.UUID, n2.UUID, "n2 uuid mismatch")
|
||||
testutils.AssertEqual(t, n2Record.BookUUID, n2.BookUUID, "n2 bookUUID mismatch")
|
||||
testutils.AssertEqual(t, n2Record.Content, n2.Content, "n2 content mismatch")
|
||||
testutils.AssertEqual(t, n2Record.Body, n2.Body, "n2 body mismatch")
|
||||
testutils.AssertEqual(t, n2Record.AddedOn, n2.AddedOn, "n2 addedOn mismatch")
|
||||
testutils.AssertEqual(t, n2Record.EditedOn, n2.EditedOn, "n2 editedOn mismatch")
|
||||
testutils.AssertEqual(t, n2Record.USN, n2.USN, "n2 usn mismatch")
|
||||
|
|
@ -793,3 +793,91 @@ func TestBookExpunge(t *testing.T) {
|
|||
testutils.AssertEqual(t, b2Record.Deleted, b2.Deleted, "b2 deleted mismatch")
|
||||
testutils.AssertEqual(t, b2Record.Dirty, b2.Dirty, "b2 dirty mismatch")
|
||||
}
|
||||
|
||||
// TestNoteFTS tests that note full text search indices stay in sync with the notes after insert, update and delete
|
||||
func TestNoteFTS(t *testing.T) {
|
||||
// set up
|
||||
ctx := testutils.InitEnv(t, "../tmp", "../testutils/fixtures/schema.sql", true)
|
||||
defer testutils.TeardownEnv(ctx)
|
||||
|
||||
// execute - insert
|
||||
n := Note{
|
||||
UUID: "n1-uuid",
|
||||
BookUUID: "b1-uuid",
|
||||
Body: "foo bar",
|
||||
AddedOn: 1542058875,
|
||||
EditedOn: 0,
|
||||
USN: 0,
|
||||
Public: false,
|
||||
Deleted: false,
|
||||
Dirty: false,
|
||||
}
|
||||
db := ctx.DB
|
||||
|
||||
tx, err := db.Begin()
|
||||
if err != nil {
|
||||
t.Fatalf(errors.Wrap(err, "beginning a transaction").Error())
|
||||
}
|
||||
|
||||
if err := n.Insert(tx); err != nil {
|
||||
tx.Rollback()
|
||||
t.Fatalf(errors.Wrap(err, "inserting").Error())
|
||||
}
|
||||
|
||||
tx.Commit()
|
||||
|
||||
// test
|
||||
var noteCount, noteFtsCount, noteSearchCount int
|
||||
testutils.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
|
||||
testutils.MustScan(t, "counting note_fts", db.QueryRow("SELECT count(*) FROM note_fts"), ¬eFtsCount)
|
||||
testutils.MustScan(t, "counting search results", db.QueryRow("SELECT count(*) FROM note_fts WHERE note_fts MATCH ?", "foo"), ¬eSearchCount)
|
||||
|
||||
testutils.AssertEqual(t, noteCount, 1, "noteCount mismatch")
|
||||
testutils.AssertEqual(t, noteFtsCount, 1, "noteFtsCount mismatch")
|
||||
testutils.AssertEqual(t, noteSearchCount, 1, "noteSearchCount mismatch")
|
||||
|
||||
// execute - update
|
||||
tx, err = db.Begin()
|
||||
if err != nil {
|
||||
t.Fatalf(errors.Wrap(err, "beginning a transaction").Error())
|
||||
}
|
||||
|
||||
n.Body = "baz quz"
|
||||
if err := n.Update(tx); err != nil {
|
||||
tx.Rollback()
|
||||
t.Fatalf(errors.Wrap(err, "updating").Error())
|
||||
}
|
||||
|
||||
tx.Commit()
|
||||
|
||||
// test
|
||||
testutils.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
|
||||
testutils.MustScan(t, "counting note_fts", db.QueryRow("SELECT count(*) FROM note_fts"), ¬eFtsCount)
|
||||
testutils.AssertEqual(t, noteCount, 1, "noteCount mismatch")
|
||||
testutils.AssertEqual(t, noteFtsCount, 1, "noteFtsCount mismatch")
|
||||
|
||||
testutils.MustScan(t, "counting search results", db.QueryRow("SELECT count(*) FROM note_fts WHERE note_fts MATCH ?", "foo"), ¬eSearchCount)
|
||||
testutils.AssertEqual(t, noteSearchCount, 0, "noteSearchCount for foo mismatch")
|
||||
testutils.MustScan(t, "counting search results", db.QueryRow("SELECT count(*) FROM note_fts WHERE note_fts MATCH ?", "baz"), ¬eSearchCount)
|
||||
testutils.AssertEqual(t, noteSearchCount, 1, "noteSearchCount for baz mismatch")
|
||||
|
||||
// execute - delete
|
||||
tx, err = db.Begin()
|
||||
if err != nil {
|
||||
t.Fatalf(errors.Wrap(err, "beginning a transaction").Error())
|
||||
}
|
||||
|
||||
if err := n.Expunge(tx); err != nil {
|
||||
tx.Rollback()
|
||||
t.Fatalf(errors.Wrap(err, "expunging").Error())
|
||||
}
|
||||
|
||||
tx.Commit()
|
||||
|
||||
// test
|
||||
testutils.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
|
||||
testutils.MustScan(t, "counting note_fts", db.QueryRow("SELECT count(*) FROM note_fts"), ¬eFtsCount)
|
||||
|
||||
testutils.AssertEqual(t, noteCount, 0, "noteCount mismatch")
|
||||
testutils.AssertEqual(t, noteFtsCount, 0, "noteFtsCount mismatch")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -150,7 +150,6 @@ func InitDB(ctx DnoteCtx) error {
|
|||
CREATE UNIQUE INDEX IF NOT EXISTS idx_books_label ON books(label);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_notes_uuid ON notes(uuid);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_books_uuid ON books(uuid);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_notes_id ON notes(id);
|
||||
CREATE INDEX IF NOT EXISTS idx_notes_book_uuid ON notes(book_uuid);`)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "creating indices")
|
||||
|
|
|
|||
3
main.go
3
main.go
|
|
@ -13,9 +13,9 @@ import (
|
|||
"github.com/dnote/cli/cmd/add"
|
||||
"github.com/dnote/cli/cmd/cat"
|
||||
"github.com/dnote/cli/cmd/edit"
|
||||
"github.com/dnote/cli/cmd/find"
|
||||
"github.com/dnote/cli/cmd/login"
|
||||
"github.com/dnote/cli/cmd/ls"
|
||||
|
||||
"github.com/dnote/cli/cmd/remove"
|
||||
"github.com/dnote/cli/cmd/sync"
|
||||
"github.com/dnote/cli/cmd/version"
|
||||
|
|
@ -46,6 +46,7 @@ func main() {
|
|||
root.Register(version.NewCmd(ctx))
|
||||
root.Register(cat.NewCmd(ctx))
|
||||
root.Register(view.NewCmd(ctx))
|
||||
root.Register(find.NewCmd(ctx))
|
||||
|
||||
if err := root.Execute(); err != nil {
|
||||
log.Errorf("%s\n", err.Error())
|
||||
|
|
|
|||
64
main_test.go
64
main_test.go
|
|
@ -18,7 +18,7 @@ import (
|
|||
var binaryName = "test-dnote"
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
if err := exec.Command("go", "build", "-o", binaryName).Run(); err != nil {
|
||||
if err := exec.Command("go", "build", "--tags", "fts5", "-o", binaryName).Run(); err != nil {
|
||||
log.Print(errors.Wrap(err, "building a binary").Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
|
@ -70,7 +70,7 @@ func TestInit(t *testing.T) {
|
|||
testutils.AssertNotEqual(t, lastSyncAt, "", "last sync at should not be empty")
|
||||
}
|
||||
|
||||
func TestAddNote_NewBook_ContentFlag(t *testing.T) {
|
||||
func TestAddNote_NewBook_BodyFlag(t *testing.T) {
|
||||
// Set up
|
||||
ctx := testutils.InitEnv(t, "./tmp", "./testutils/fixtures/schema.sql", true)
|
||||
defer testutils.TeardownEnv(ctx)
|
||||
|
|
@ -92,17 +92,17 @@ func TestAddNote_NewBook_ContentFlag(t *testing.T) {
|
|||
testutils.MustScan(t, "getting book", db.QueryRow("SELECT uuid, dirty FROM books where label = ?", "js"), &book.UUID, &book.Dirty)
|
||||
var note core.Note
|
||||
testutils.MustScan(t, "getting note",
|
||||
db.QueryRow("SELECT uuid, content, added_on, dirty FROM notes where book_uuid = ?", book.UUID), ¬e.UUID, ¬e.Content, ¬e.AddedOn, ¬e.Dirty)
|
||||
db.QueryRow("SELECT uuid, body, added_on, dirty FROM notes where book_uuid = ?", book.UUID), ¬e.UUID, ¬e.Body, ¬e.AddedOn, ¬e.Dirty)
|
||||
|
||||
testutils.AssertEqual(t, book.Dirty, true, "Book dirty mismatch")
|
||||
|
||||
testutils.AssertNotEqual(t, note.UUID, "", "Note should have UUID")
|
||||
testutils.AssertEqual(t, note.Content, "foo", "Note content mismatch")
|
||||
testutils.AssertEqual(t, note.Body, "foo", "Note body mismatch")
|
||||
testutils.AssertEqual(t, note.Dirty, true, "Note dirty mismatch")
|
||||
testutils.AssertNotEqual(t, note.AddedOn, int64(0), "Note added_on mismatch")
|
||||
}
|
||||
|
||||
func TestAddNote_ExistingBook_ContentFlag(t *testing.T) {
|
||||
func TestAddNote_ExistingBook_BodyFlag(t *testing.T) {
|
||||
// Set up
|
||||
ctx := testutils.InitEnv(t, "./tmp", "./testutils/fixtures/schema.sql", true)
|
||||
defer testutils.TeardownEnv(ctx)
|
||||
|
|
@ -124,9 +124,9 @@ func TestAddNote_ExistingBook_ContentFlag(t *testing.T) {
|
|||
|
||||
var n1, n2 core.Note
|
||||
testutils.MustScan(t, "getting n1",
|
||||
db.QueryRow("SELECT uuid, content, added_on, dirty FROM notes WHERE book_uuid = ? AND uuid = ?", "js-book-uuid", "43827b9a-c2b0-4c06-a290-97991c896653"), &n1.UUID, &n1.Content, &n1.AddedOn, &n1.Dirty)
|
||||
db.QueryRow("SELECT uuid, body, added_on, dirty FROM notes WHERE book_uuid = ? AND uuid = ?", "js-book-uuid", "43827b9a-c2b0-4c06-a290-97991c896653"), &n1.UUID, &n1.Body, &n1.AddedOn, &n1.Dirty)
|
||||
testutils.MustScan(t, "getting n2",
|
||||
db.QueryRow("SELECT uuid, content, added_on, dirty FROM notes WHERE book_uuid = ? AND content = ?", "js-book-uuid", "foo"), &n2.UUID, &n2.Content, &n2.AddedOn, &n2.Dirty)
|
||||
db.QueryRow("SELECT uuid, body, added_on, dirty FROM notes WHERE book_uuid = ? AND body = ?", "js-book-uuid", "foo"), &n2.UUID, &n2.Body, &n2.AddedOn, &n2.Dirty)
|
||||
|
||||
var book core.Book
|
||||
testutils.MustScan(t, "getting book", db.QueryRow("SELECT dirty FROM books where label = ?", "js"), &book.Dirty)
|
||||
|
|
@ -134,16 +134,16 @@ func TestAddNote_ExistingBook_ContentFlag(t *testing.T) {
|
|||
testutils.AssertEqual(t, book.Dirty, false, "Book dirty mismatch")
|
||||
|
||||
testutils.AssertNotEqual(t, n1.UUID, "", "n1 should have UUID")
|
||||
testutils.AssertEqual(t, n1.Content, "Booleans have toString()", "n1 content mismatch")
|
||||
testutils.AssertEqual(t, n1.Body, "Booleans have toString()", "n1 body mismatch")
|
||||
testutils.AssertEqual(t, n1.AddedOn, int64(1515199943), "n1 added_on mismatch")
|
||||
testutils.AssertEqual(t, n1.Dirty, false, "n1 dirty mismatch")
|
||||
|
||||
testutils.AssertNotEqual(t, n2.UUID, "", "n2 should have UUID")
|
||||
testutils.AssertEqual(t, n2.Content, "foo", "n2 content mismatch")
|
||||
testutils.AssertEqual(t, n2.Body, "foo", "n2 body mismatch")
|
||||
testutils.AssertEqual(t, n2.Dirty, true, "n2 dirty mismatch")
|
||||
}
|
||||
|
||||
func TestEditNote_ContentFlag(t *testing.T) {
|
||||
func TestEditNote_BodyFlag(t *testing.T) {
|
||||
// Set up
|
||||
ctx := testutils.InitEnv(t, "./tmp", "./testutils/fixtures/schema.sql", true)
|
||||
defer testutils.TeardownEnv(ctx)
|
||||
|
|
@ -165,16 +165,16 @@ func TestEditNote_ContentFlag(t *testing.T) {
|
|||
|
||||
var n1, n2 core.Note
|
||||
testutils.MustScan(t, "getting n1",
|
||||
db.QueryRow("SELECT uuid, content, added_on, dirty FROM notes where book_uuid = ? AND uuid = ?", "js-book-uuid", "43827b9a-c2b0-4c06-a290-97991c896653"), &n1.UUID, &n1.Content, &n1.AddedOn, &n1.Dirty)
|
||||
db.QueryRow("SELECT uuid, body, added_on, dirty FROM notes where book_uuid = ? AND uuid = ?", "js-book-uuid", "43827b9a-c2b0-4c06-a290-97991c896653"), &n1.UUID, &n1.Body, &n1.AddedOn, &n1.Dirty)
|
||||
testutils.MustScan(t, "getting n2",
|
||||
db.QueryRow("SELECT uuid, content, added_on, dirty FROM notes where book_uuid = ? AND uuid = ?", "js-book-uuid", "f0d0fbb7-31ff-45ae-9f0f-4e429c0c797f"), &n2.UUID, &n2.Content, &n2.AddedOn, &n2.Dirty)
|
||||
db.QueryRow("SELECT uuid, body, added_on, dirty FROM notes where book_uuid = ? AND uuid = ?", "js-book-uuid", "f0d0fbb7-31ff-45ae-9f0f-4e429c0c797f"), &n2.UUID, &n2.Body, &n2.AddedOn, &n2.Dirty)
|
||||
|
||||
testutils.AssertEqual(t, n1.UUID, "43827b9a-c2b0-4c06-a290-97991c896653", "n1 should have UUID")
|
||||
testutils.AssertEqual(t, n1.Content, "Booleans have toString()", "n1 content mismatch")
|
||||
testutils.AssertEqual(t, n1.Body, "Booleans have toString()", "n1 body mismatch")
|
||||
testutils.AssertEqual(t, n1.Dirty, false, "n1 dirty mismatch")
|
||||
|
||||
testutils.AssertEqual(t, n2.UUID, "f0d0fbb7-31ff-45ae-9f0f-4e429c0c797f", "Note should have UUID")
|
||||
testutils.AssertEqual(t, n2.Content, "foo bar", "Note content mismatch")
|
||||
testutils.AssertEqual(t, n2.Body, "foo bar", "Note body mismatch")
|
||||
testutils.AssertEqual(t, n2.Dirty, true, "n2 dirty mismatch")
|
||||
testutils.AssertNotEqual(t, n2.EditedOn, 0, "Note edited_on mismatch")
|
||||
}
|
||||
|
|
@ -212,14 +212,14 @@ func TestRemoveNote(t *testing.T) {
|
|||
db.QueryRow("SELECT label, deleted, usn FROM books WHERE uuid = ?", "linux-book-uuid"),
|
||||
&b2.Label, &b2.Deleted, &b2.USN)
|
||||
testutils.MustScan(t, "getting n1",
|
||||
db.QueryRow("SELECT uuid, content, added_on, deleted, dirty, usn FROM notes WHERE book_uuid = ? AND id = ?", "js-book-uuid", 1),
|
||||
&n1.UUID, &n1.Content, &n1.AddedOn, &n1.Deleted, &n1.Dirty, &n1.USN)
|
||||
db.QueryRow("SELECT uuid, body, added_on, deleted, dirty, usn FROM notes WHERE book_uuid = ? AND uuid = ?", "js-book-uuid", "f0d0fbb7-31ff-45ae-9f0f-4e429c0c797f"),
|
||||
&n1.UUID, &n1.Body, &n1.AddedOn, &n1.Deleted, &n1.Dirty, &n1.USN)
|
||||
testutils.MustScan(t, "getting n2",
|
||||
db.QueryRow("SELECT uuid, content, added_on, deleted, dirty, usn FROM notes WHERE book_uuid = ? AND id = ?", "js-book-uuid", 2),
|
||||
&n2.UUID, &n2.Content, &n2.AddedOn, &n2.Deleted, &n2.Dirty, &n2.USN)
|
||||
db.QueryRow("SELECT uuid, body, added_on, deleted, dirty, usn FROM notes WHERE book_uuid = ? AND uuid = ?", "js-book-uuid", "43827b9a-c2b0-4c06-a290-97991c896653"),
|
||||
&n2.UUID, &n2.Body, &n2.AddedOn, &n2.Deleted, &n2.Dirty, &n2.USN)
|
||||
testutils.MustScan(t, "getting n3",
|
||||
db.QueryRow("SELECT uuid, content, added_on, deleted, dirty, usn FROM notes WHERE book_uuid = ? AND id = ?", "linux-book-uuid", 3),
|
||||
&n3.UUID, &n3.Content, &n3.AddedOn, &n3.Deleted, &n3.Dirty, &n3.USN)
|
||||
db.QueryRow("SELECT uuid, body, added_on, deleted, dirty, usn FROM notes WHERE book_uuid = ? AND uuid = ?", "linux-book-uuid", "3e065d55-6d47-42f2-a6bf-f5844130b2d2"),
|
||||
&n3.UUID, &n3.Body, &n3.AddedOn, &n3.Deleted, &n3.Dirty, &n3.USN)
|
||||
|
||||
testutils.AssertEqual(t, b1.Label, "js", "b1 label mismatch")
|
||||
testutils.AssertEqual(t, b1.Deleted, false, "b1 deleted mismatch")
|
||||
|
|
@ -232,19 +232,19 @@ func TestRemoveNote(t *testing.T) {
|
|||
testutils.AssertEqual(t, b2.USN, 122, "b2 usn mismatch")
|
||||
|
||||
testutils.AssertEqual(t, n1.UUID, "f0d0fbb7-31ff-45ae-9f0f-4e429c0c797f", "n1 should have UUID")
|
||||
testutils.AssertEqual(t, n1.Content, "", "n1 content mismatch")
|
||||
testutils.AssertEqual(t, n1.Body, "", "n1 body mismatch")
|
||||
testutils.AssertEqual(t, n1.Deleted, true, "n1 deleted mismatch")
|
||||
testutils.AssertEqual(t, n1.Dirty, true, "n1 Dirty mismatch")
|
||||
testutils.AssertEqual(t, n1.USN, 11, "n1 usn mismatch")
|
||||
|
||||
testutils.AssertEqual(t, n2.UUID, "43827b9a-c2b0-4c06-a290-97991c896653", "n2 should have UUID")
|
||||
testutils.AssertEqual(t, n2.Content, "n2 content", "n2 content mismatch")
|
||||
testutils.AssertEqual(t, n2.Body, "n2 body", "n2 body mismatch")
|
||||
testutils.AssertEqual(t, n2.Deleted, false, "n2 deleted mismatch")
|
||||
testutils.AssertEqual(t, n2.Dirty, false, "n2 Dirty mismatch")
|
||||
testutils.AssertEqual(t, n2.USN, 12, "n2 usn mismatch")
|
||||
|
||||
testutils.AssertEqual(t, n3.UUID, "3e065d55-6d47-42f2-a6bf-f5844130b2d2", "n3 should have UUID")
|
||||
testutils.AssertEqual(t, n3.Content, "n3 content", "n3 content mismatch")
|
||||
testutils.AssertEqual(t, n3.Body, "n3 body", "n3 body mismatch")
|
||||
testutils.AssertEqual(t, n3.Deleted, false, "n3 deleted mismatch")
|
||||
testutils.AssertEqual(t, n3.Dirty, false, "n3 Dirty mismatch")
|
||||
testutils.AssertEqual(t, n3.USN, 13, "n3 usn mismatch")
|
||||
|
|
@ -283,14 +283,14 @@ func TestRemoveBook(t *testing.T) {
|
|||
db.QueryRow("SELECT label, dirty, deleted, usn FROM books WHERE uuid = ?", "linux-book-uuid"),
|
||||
&b2.Label, &b2.Dirty, &b2.Deleted, &b2.USN)
|
||||
testutils.MustScan(t, "getting n1",
|
||||
db.QueryRow("SELECT uuid, content, added_on, dirty, deleted, usn FROM notes WHERE book_uuid = ? AND id = ?", "js-book-uuid", 1),
|
||||
&n1.UUID, &n1.Content, &n1.AddedOn, &n1.Deleted, &n1.Dirty, &n1.USN)
|
||||
db.QueryRow("SELECT uuid, body, added_on, dirty, deleted, usn FROM notes WHERE book_uuid = ? AND uuid = ?", "js-book-uuid", "f0d0fbb7-31ff-45ae-9f0f-4e429c0c797f"),
|
||||
&n1.UUID, &n1.Body, &n1.AddedOn, &n1.Deleted, &n1.Dirty, &n1.USN)
|
||||
testutils.MustScan(t, "getting n2",
|
||||
db.QueryRow("SELECT uuid, content, added_on, dirty, deleted, usn FROM notes WHERE book_uuid = ? AND id = ?", "js-book-uuid", 2),
|
||||
&n2.UUID, &n2.Content, &n2.AddedOn, &n2.Deleted, &n2.Dirty, &n2.USN)
|
||||
db.QueryRow("SELECT uuid, body, added_on, dirty, deleted, usn FROM notes WHERE book_uuid = ? AND uuid = ?", "js-book-uuid", "43827b9a-c2b0-4c06-a290-97991c896653"),
|
||||
&n2.UUID, &n2.Body, &n2.AddedOn, &n2.Deleted, &n2.Dirty, &n2.USN)
|
||||
testutils.MustScan(t, "getting n3",
|
||||
db.QueryRow("SELECT uuid, content, added_on, dirty, deleted, usn FROM notes WHERE book_uuid = ? AND id = ?", "linux-book-uuid", 3),
|
||||
&n3.UUID, &n3.Content, &n3.AddedOn, &n3.Deleted, &n3.Dirty, &n3.USN)
|
||||
db.QueryRow("SELECT uuid, body, added_on, dirty, deleted, usn FROM notes WHERE book_uuid = ? AND uuid = ?", "linux-book-uuid", "3e065d55-6d47-42f2-a6bf-f5844130b2d2"),
|
||||
&n3.UUID, &n3.Body, &n3.AddedOn, &n3.Deleted, &n3.Dirty, &n3.USN)
|
||||
|
||||
testutils.AssertNotEqual(t, b1.Label, "js", "b1 label mismatch")
|
||||
testutils.AssertEqual(t, b1.Dirty, true, "b1 Dirty mismatch")
|
||||
|
|
@ -303,19 +303,19 @@ func TestRemoveBook(t *testing.T) {
|
|||
testutils.AssertEqual(t, b2.USN, 122, "b2 usn mismatch")
|
||||
|
||||
testutils.AssertEqual(t, n1.UUID, "f0d0fbb7-31ff-45ae-9f0f-4e429c0c797f", "n1 should have UUID")
|
||||
testutils.AssertEqual(t, n1.Content, "", "n1 content mismatch")
|
||||
testutils.AssertEqual(t, n1.Body, "", "n1 body mismatch")
|
||||
testutils.AssertEqual(t, n1.Dirty, true, "n1 Dirty mismatch")
|
||||
testutils.AssertEqual(t, n1.Deleted, true, "n1 deleted mismatch")
|
||||
testutils.AssertEqual(t, n1.USN, 11, "n1 usn mismatch")
|
||||
|
||||
testutils.AssertEqual(t, n2.UUID, "43827b9a-c2b0-4c06-a290-97991c896653", "n2 should have UUID")
|
||||
testutils.AssertEqual(t, n2.Content, "", "n2 content mismatch")
|
||||
testutils.AssertEqual(t, n2.Body, "", "n2 body mismatch")
|
||||
testutils.AssertEqual(t, n2.Dirty, true, "n2 Dirty mismatch")
|
||||
testutils.AssertEqual(t, n2.Deleted, true, "n2 deleted mismatch")
|
||||
testutils.AssertEqual(t, n2.USN, 12, "n2 usn mismatch")
|
||||
|
||||
testutils.AssertEqual(t, n3.UUID, "3e065d55-6d47-42f2-a6bf-f5844130b2d2", "n3 should have UUID")
|
||||
testutils.AssertEqual(t, n3.Content, "n3 content", "n3 content mismatch")
|
||||
testutils.AssertEqual(t, n3.Body, "n3 body", "n3 body mismatch")
|
||||
testutils.AssertEqual(t, n3.Dirty, false, "n3 Dirty mismatch")
|
||||
testutils.AssertEqual(t, n3.Deleted, false, "n3 deleted mismatch")
|
||||
testutils.AssertEqual(t, n3.USN, 13, "n3 usn mismatch")
|
||||
|
|
|
|||
25
migrate/fixtures/local-8-pre-schema.sql
Normal file
25
migrate/fixtures/local-8-pre-schema.sql
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
CREATE TABLE notes
|
||||
(
|
||||
id integer PRIMARY KEY AUTOINCREMENT,
|
||||
uuid text NOT NULL,
|
||||
book_uuid text NOT NULL,
|
||||
content text NOT NULL,
|
||||
added_on integer NOT NULL,
|
||||
edited_on integer DEFAULT 0,
|
||||
public bool DEFAULT false
|
||||
, dirty bool DEFAULT false, usn int DEFAULT 0 NOT NULL, deleted bool DEFAULT false);
|
||||
CREATE TABLE books
|
||||
(
|
||||
uuid text PRIMARY KEY,
|
||||
label text NOT NULL
|
||||
, dirty bool DEFAULT false, usn int DEFAULT 0 NOT NULL, deleted bool DEFAULT false);
|
||||
CREATE TABLE system
|
||||
(
|
||||
key string NOT NULL,
|
||||
value text NOT NULL
|
||||
);
|
||||
CREATE UNIQUE INDEX idx_books_label ON books(label);
|
||||
CREATE UNIQUE INDEX idx_notes_uuid ON notes(uuid);
|
||||
CREATE UNIQUE INDEX idx_books_uuid ON books(uuid);
|
||||
CREATE UNIQUE INDEX idx_notes_id ON notes(id);
|
||||
CREATE INDEX idx_notes_book_uuid ON notes(book_uuid);
|
||||
23
migrate/fixtures/local-9-pre-schema.sql
Normal file
23
migrate/fixtures/local-9-pre-schema.sql
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
CREATE TABLE notes
|
||||
(
|
||||
uuid text NOT NULL,
|
||||
book_uuid text NOT NULL,
|
||||
body text NOT NULL,
|
||||
added_on integer NOT NULL,
|
||||
edited_on integer DEFAULT 0,
|
||||
public bool DEFAULT false
|
||||
, dirty bool DEFAULT false, usn int DEFAULT 0 NOT NULL, deleted bool DEFAULT false);
|
||||
CREATE TABLE books
|
||||
(
|
||||
uuid text PRIMARY KEY,
|
||||
label text NOT NULL
|
||||
, dirty bool DEFAULT false, usn int DEFAULT 0 NOT NULL, deleted bool DEFAULT false);
|
||||
CREATE TABLE system
|
||||
(
|
||||
key string NOT NULL,
|
||||
value text NOT NULL
|
||||
);
|
||||
CREATE UNIQUE INDEX idx_books_label ON books(label);
|
||||
CREATE UNIQUE INDEX idx_notes_uuid ON notes(uuid);
|
||||
CREATE UNIQUE INDEX idx_books_uuid ON books(uuid);
|
||||
CREATE INDEX idx_notes_book_uuid ON notes(book_uuid);
|
||||
|
|
@ -23,6 +23,9 @@ var LocalSequence = []migration{
|
|||
lm4,
|
||||
lm5,
|
||||
lm6,
|
||||
lm7,
|
||||
lm8,
|
||||
lm9,
|
||||
}
|
||||
|
||||
// RemoteSequence is a list of remote migrations to be run
|
||||
|
|
|
|||
|
|
@ -763,6 +763,116 @@ func TestLocalMigration7_conflicts_dup(t *testing.T) {
|
|||
testutils.AssertEqual(t, b2Dirty, false, "b2 should not have been marked dirty")
|
||||
}
|
||||
|
||||
func TestLocalMigration8(t *testing.T) {
|
||||
// set up
|
||||
ctx := testutils.InitEnv(t, "../tmp", "./fixtures/local-8-pre-schema.sql", false)
|
||||
defer testutils.TeardownEnv(ctx)
|
||||
|
||||
db := ctx.DB
|
||||
|
||||
b1UUID := utils.GenerateUUID()
|
||||
testutils.MustExec(t, "inserting book 1", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "b1")
|
||||
|
||||
n1UUID := utils.GenerateUUID()
|
||||
testutils.MustExec(t, "inserting n1", db, `INSERT INTO notes
|
||||
(id, uuid, book_uuid, content, added_on, edited_on, public, dirty, usn, deleted) VALUES
|
||||
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, 1, n1UUID, b1UUID, "n1 Body", 1, 2, true, true, 20, false)
|
||||
n2UUID := utils.GenerateUUID()
|
||||
testutils.MustExec(t, "inserting n2", db, `INSERT INTO notes
|
||||
(id, uuid, book_uuid, content, added_on, edited_on, public, dirty, usn, deleted) VALUES
|
||||
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, 2, n2UUID, b1UUID, "", 3, 4, false, true, 21, true)
|
||||
|
||||
// Execute
|
||||
tx, err := db.Begin()
|
||||
if err != nil {
|
||||
t.Fatal(errors.Wrap(err, "beginning a transaction"))
|
||||
}
|
||||
|
||||
err = lm8.run(ctx, tx)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
t.Fatal(errors.Wrap(err, "failed to run"))
|
||||
}
|
||||
|
||||
tx.Commit()
|
||||
|
||||
// Test
|
||||
var n1BookUUID, n1Body string
|
||||
var n1AddedOn, n1EditedOn int64
|
||||
var n1USN int
|
||||
var n1Public, n1Dirty, n1Deleted bool
|
||||
testutils.MustScan(t, "scanning n1", db.QueryRow("SELECT book_uuid, body, added_on, edited_on, usn, public, dirty, deleted FROM notes WHERE uuid = ?", n1UUID), &n1BookUUID, &n1Body, &n1AddedOn, &n1EditedOn, &n1USN, &n1Public, &n1Dirty, &n1Deleted)
|
||||
|
||||
var n2BookUUID, n2Body string
|
||||
var n2AddedOn, n2EditedOn int64
|
||||
var n2USN int
|
||||
var n2Public, n2Dirty, n2Deleted bool
|
||||
testutils.MustScan(t, "scanning n2", db.QueryRow("SELECT book_uuid, body, added_on, edited_on, usn, public, dirty, deleted FROM notes WHERE uuid = ?", n2UUID), &n2BookUUID, &n2Body, &n2AddedOn, &n2EditedOn, &n2USN, &n2Public, &n2Dirty, &n2Deleted)
|
||||
|
||||
testutils.AssertEqual(t, n1BookUUID, b1UUID, "n1 BookUUID mismatch")
|
||||
testutils.AssertEqual(t, n1Body, "n1 Body", "n1 Body mismatch")
|
||||
testutils.AssertEqual(t, n1AddedOn, int64(1), "n1 AddedOn mismatch")
|
||||
testutils.AssertEqual(t, n1EditedOn, int64(2), "n1 EditedOn mismatch")
|
||||
testutils.AssertEqual(t, n1USN, 20, "n1 USN mismatch")
|
||||
testutils.AssertEqual(t, n1Public, true, "n1 Public mismatch")
|
||||
testutils.AssertEqual(t, n1Dirty, true, "n1 Dirty mismatch")
|
||||
testutils.AssertEqual(t, n1Deleted, false, "n1 Deleted mismatch")
|
||||
|
||||
testutils.AssertEqual(t, n2BookUUID, b1UUID, "n2 BookUUID mismatch")
|
||||
testutils.AssertEqual(t, n2Body, "", "n2 Body mismatch")
|
||||
testutils.AssertEqual(t, n2AddedOn, int64(3), "n2 AddedOn mismatch")
|
||||
testutils.AssertEqual(t, n2EditedOn, int64(4), "n2 EditedOn mismatch")
|
||||
testutils.AssertEqual(t, n2USN, 21, "n2 USN mismatch")
|
||||
testutils.AssertEqual(t, n2Public, false, "n2 Public mismatch")
|
||||
testutils.AssertEqual(t, n2Dirty, true, "n2 Dirty mismatch")
|
||||
testutils.AssertEqual(t, n2Deleted, true, "n2 Deleted mismatch")
|
||||
}
|
||||
|
||||
func TestLocalMigration9(t *testing.T) {
|
||||
// set up
|
||||
ctx := testutils.InitEnv(t, "../tmp", "./fixtures/local-9-pre-schema.sql", false)
|
||||
defer testutils.TeardownEnv(ctx)
|
||||
|
||||
db := ctx.DB
|
||||
|
||||
b1UUID := utils.GenerateUUID()
|
||||
testutils.MustExec(t, "inserting book 1", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "b1")
|
||||
|
||||
n1UUID := utils.GenerateUUID()
|
||||
testutils.MustExec(t, "inserting n1", db, `INSERT INTO notes
|
||||
(uuid, book_uuid, body, added_on, edited_on, public, dirty, usn, deleted) VALUES
|
||||
(?, ?, ?, ?, ?, ?, ?, ?, ?)`, n1UUID, b1UUID, "n1 Body", 1, 2, true, true, 20, false)
|
||||
n2UUID := utils.GenerateUUID()
|
||||
testutils.MustExec(t, "inserting n2", db, `INSERT INTO notes
|
||||
(uuid, book_uuid, body, added_on, edited_on, public, dirty, usn, deleted) VALUES
|
||||
(?, ?, ?, ?, ?, ?, ?, ?, ?)`, n2UUID, b1UUID, "n2 Body", 3, 4, false, true, 21, false)
|
||||
|
||||
// Execute
|
||||
tx, err := db.Begin()
|
||||
if err != nil {
|
||||
t.Fatal(errors.Wrap(err, "beginning a transaction"))
|
||||
}
|
||||
|
||||
err = lm9.run(ctx, tx)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
t.Fatal(errors.Wrap(err, "failed to run"))
|
||||
}
|
||||
|
||||
tx.Commit()
|
||||
|
||||
// Test
|
||||
|
||||
// assert that note_fts was populated with correct values
|
||||
var noteFtsCount int
|
||||
testutils.MustScan(t, "counting note_fts", db.QueryRow("SELECT count(*) FROM note_fts;"), ¬eFtsCount)
|
||||
testutils.AssertEqual(t, noteFtsCount, 2, "noteFtsCount mismatch")
|
||||
|
||||
var resCount int
|
||||
testutils.MustScan(t, "counting result", db.QueryRow("SELECT count(*) FROM note_fts WHERE note_fts MATCH ?", "n1"), &resCount)
|
||||
testutils.AssertEqual(t, resCount, 1, "noteFtsCount mismatch")
|
||||
}
|
||||
|
||||
func TestRemoteMigration1(t *testing.T) {
|
||||
// set up
|
||||
ctx := testutils.InitEnv(t, "../tmp", "./fixtures/remote-1-pre-schema.sql", false)
|
||||
|
|
|
|||
|
|
@ -311,6 +311,81 @@ var lm7 = migration{
|
|||
},
|
||||
}
|
||||
|
||||
var lm8 = migration{
|
||||
name: "drop-note-id-and-rename-content-to-body",
|
||||
run: func(ctx infra.DnoteCtx, tx *sql.Tx) error {
|
||||
_, err := tx.Exec(`CREATE TABLE notes_tmp
|
||||
(
|
||||
uuid text NOT NULL,
|
||||
book_uuid text NOT NULL,
|
||||
body text NOT NULL,
|
||||
added_on integer NOT NULL,
|
||||
edited_on integer DEFAULT 0,
|
||||
public bool DEFAULT false,
|
||||
dirty bool DEFAULT false,
|
||||
usn int DEFAULT 0 NOT NULL,
|
||||
deleted bool DEFAULT false
|
||||
);`)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "creating temporary notes table for migration")
|
||||
}
|
||||
|
||||
_, err = tx.Exec(`INSERT INTO notes_tmp
|
||||
SELECT uuid, book_uuid, content, added_on, edited_on, public, dirty, usn, deleted FROM notes;`)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "copying data to new table")
|
||||
}
|
||||
|
||||
_, err = tx.Exec(`DROP TABLE notes;`)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "dropping the notes table")
|
||||
}
|
||||
|
||||
_, err = tx.Exec(`ALTER TABLE notes_tmp RENAME to notes;`)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "renaming the temporary notes table")
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var lm9 = migration{
|
||||
name: "create-fts-index",
|
||||
run: func(ctx infra.DnoteCtx, tx *sql.Tx) error {
|
||||
_, err := tx.Exec(`CREATE VIRTUAL TABLE IF NOT EXISTS note_fts USING fts5(content=notes, body, tokenize="porter unicode61 categories 'L* N* Co Ps Pe'");`)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "creating note_fts")
|
||||
}
|
||||
|
||||
// Create triggers to keep the indices in note_fts in sync with notes
|
||||
_, err = tx.Exec(`
|
||||
CREATE TRIGGER notes_after_insert AFTER INSERT ON notes BEGIN
|
||||
INSERT INTO note_fts(rowid, body) VALUES (new.rowid, new.body);
|
||||
END;
|
||||
CREATE TRIGGER notes_after_delete AFTER DELETE ON notes BEGIN
|
||||
INSERT INTO note_fts(note_fts, rowid, body) VALUES ('delete', old.rowid, old.body);
|
||||
END;
|
||||
CREATE TRIGGER notes_after_update AFTER UPDATE ON notes BEGIN
|
||||
INSERT INTO note_fts(note_fts, rowid, body) VALUES ('delete', old.rowid, old.body);
|
||||
INSERT INTO note_fts(rowid, body) VALUES (new.rowid, new.body);
|
||||
END;
|
||||
`)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "creating triggers for note_fts")
|
||||
}
|
||||
|
||||
// populate fts indices
|
||||
_, err = tx.Exec(`INSERT INTO note_fts (rowid, body)
|
||||
SELECT rowid, body FROM notes;`)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "populating note_fts")
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var rm1 = migration{
|
||||
name: "sync-book-uuids-from-server",
|
||||
run: func(ctx infra.DnoteCtx, tx *sql.Tx) error {
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@ build() {
|
|||
|
||||
pushd "$basedir"
|
||||
|
||||
# TODO: do i need to pass fts5 tag?
|
||||
|
||||
# build linux
|
||||
xgo --targets="linux/amd64"\
|
||||
-ldflags "-X main.apiEndpoint=https://api.dnote.io -X main.versionTag=$version" .
|
||||
|
|
|
|||
|
|
@ -5,6 +5,6 @@
|
|||
sudo rm "$(which dnote)" $GOPATH/bin/cli
|
||||
|
||||
# change tags to darwin if on macos
|
||||
go install -ldflags "-X main.apiEndpoint=http://127.0.0.1:5000" --tags "linux" .
|
||||
go install -ldflags "-X main.apiEndpoint=http://127.0.0.1:5000" --tags "linux fts5" .
|
||||
|
||||
sudo ln -s $GOPATH/bin/cli /usr/local/bin/dnote
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
set -eu
|
||||
|
||||
homebrewRepoDir="$GOPATH"/src/github.com/dnote/homebrew-dnote
|
||||
|
||||
command_exists () {
|
||||
command -v "$1" >/dev/null 2>&1;
|
||||
}
|
||||
|
|
@ -24,6 +26,13 @@ if ! command_exists hub; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -d $homebrewRepoDir ]; then
|
||||
echo "homebrew-dnote not found locally. did you clone it?"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -d ]
|
||||
|
||||
# 1. push tag
|
||||
version=$1
|
||||
version_tag="v$version"
|
||||
|
|
@ -48,4 +57,4 @@ hub release create \
|
|||
|
||||
# 3. Release on Homebrew
|
||||
homebrew_sha256=$(shasum -a 256 "./build/dnote_${version}_darwin_amd64.tar.gz" | cut -d ' ' -f 1)
|
||||
(cd "$GOPATH"/src/github.com/dnote/homebrew-dnote && ./release.sh "$version" "$homebrew_sha256")
|
||||
(cd $homebrewRepoDir && ./release.sh "$version" "$homebrew_sha256")
|
||||
|
|
|
|||
|
|
@ -7,5 +7,6 @@
|
|||
rm -rf ./tmp
|
||||
|
||||
# run test
|
||||
go test ./... -p 1
|
||||
|
||||
go test ./... \
|
||||
-p 1\
|
||||
--tags "fts5"
|
||||
|
|
|
|||
|
|
@ -1,13 +1,3 @@
|
|||
CREATE TABLE notes
|
||||
(
|
||||
id integer PRIMARY KEY AUTOINCREMENT,
|
||||
uuid text NOT NULL,
|
||||
book_uuid text NOT NULL,
|
||||
content text NOT NULL,
|
||||
added_on integer NOT NULL,
|
||||
edited_on integer DEFAULT 0,
|
||||
public bool DEFAULT false
|
||||
, dirty bool DEFAULT false, usn int DEFAULT 0 NOT NULL, deleted bool DEFAULT false);
|
||||
CREATE TABLE books
|
||||
(
|
||||
uuid text PRIMARY KEY,
|
||||
|
|
@ -19,7 +9,43 @@ CREATE TABLE system
|
|||
value text NOT NULL
|
||||
);
|
||||
CREATE UNIQUE INDEX idx_books_label ON books(label);
|
||||
CREATE UNIQUE INDEX idx_notes_uuid ON notes(uuid);
|
||||
CREATE UNIQUE INDEX idx_books_uuid ON books(uuid);
|
||||
CREATE UNIQUE INDEX idx_notes_id ON notes(id);
|
||||
CREATE TABLE actions
|
||||
(
|
||||
uuid text PRIMARY KEY,
|
||||
schema integer NOT NULL,
|
||||
type text NOT NULL,
|
||||
data text NOT NULL,
|
||||
timestamp integer NOT NULL
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS "notes"
|
||||
(
|
||||
uuid text NOT NULL,
|
||||
book_uuid text NOT NULL,
|
||||
body text NOT NULL,
|
||||
added_on integer NOT NULL,
|
||||
edited_on integer DEFAULT 0,
|
||||
public bool DEFAULT false,
|
||||
dirty bool DEFAULT false,
|
||||
usn int DEFAULT 0 NOT NULL,
|
||||
deleted bool DEFAULT false
|
||||
);
|
||||
CREATE VIRTUAL TABLE note_fts
|
||||
USING fts5(content=notes, body, tokenize = "unicode61")
|
||||
/* note_fts(body) */;
|
||||
CREATE TABLE IF NOT EXISTS 'note_fts_data'(id INTEGER PRIMARY KEY, block BLOB);
|
||||
CREATE TABLE IF NOT EXISTS 'note_fts_idx'(segid, term, pgno, PRIMARY KEY(segid, term)) WITHOUT ROWID;
|
||||
CREATE TABLE IF NOT EXISTS 'note_fts_docsize'(id INTEGER PRIMARY KEY, sz BLOB);
|
||||
CREATE TABLE IF NOT EXISTS 'note_fts_config'(k PRIMARY KEY, v) WITHOUT ROWID;
|
||||
CREATE TRIGGER notes_after_insert AFTER INSERT ON notes BEGIN
|
||||
INSERT INTO note_fts(rowid, body) VALUES (new.rowid, new.body);
|
||||
END;
|
||||
CREATE TRIGGER notes_after_delete AFTER DELETE ON notes BEGIN
|
||||
INSERT INTO note_fts(note_fts, rowid, body) VALUES ('delete', old.rowid, old.body);
|
||||
END;
|
||||
CREATE TRIGGER notes_after_update AFTER UPDATE ON notes BEGIN
|
||||
INSERT INTO note_fts(note_fts, rowid, body) VALUES ('delete', old.rowid, old.body);
|
||||
INSERT INTO note_fts(rowid, body) VALUES (new.rowid, new.body);
|
||||
END;
|
||||
CREATE UNIQUE INDEX idx_notes_uuid ON notes(uuid);
|
||||
CREATE INDEX idx_notes_book_uuid ON notes(book_uuid);
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ func InitEnv(t *testing.T, relPath string, relFixturePath string, migrated bool)
|
|||
|
||||
if migrated {
|
||||
// mark migrations as done. When adding new migrations, bump the numbers here.
|
||||
if _, err := db.Exec("INSERT INTO system (key, value) VALUES (? , ?);", infra.SystemSchema, 6); err != nil {
|
||||
if _, err := db.Exec("INSERT INTO system (key, value) VALUES (? , ?);", infra.SystemSchema, 9); err != nil {
|
||||
t.Fatal(errors.Wrap(err, "inserting schema"))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ func Setup1(t *testing.T, ctx infra.DnoteCtx) {
|
|||
MustExec(t, "setting up book 1", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "js")
|
||||
MustExec(t, "setting up book 2", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b2UUID, "linux")
|
||||
|
||||
MustExec(t, "setting up note 1", db, "INSERT INTO notes (uuid, book_uuid, content, added_on) VALUES (?, ?, ?, ?)", "43827b9a-c2b0-4c06-a290-97991c896653", b1UUID, "Booleans have toString()", 1515199943)
|
||||
MustExec(t, "setting up note 1", db, "INSERT INTO notes (uuid, book_uuid, body, added_on) VALUES (?, ?, ?, ?)", "43827b9a-c2b0-4c06-a290-97991c896653", b1UUID, "Booleans have toString()", 1515199943)
|
||||
}
|
||||
|
||||
// Setup2 sets up a dnote env #2
|
||||
|
|
@ -30,9 +30,9 @@ func Setup2(t *testing.T, ctx infra.DnoteCtx) {
|
|||
MustExec(t, "setting up book 1", db, "INSERT INTO books (uuid, label, usn) VALUES (?, ?, ?)", b1UUID, "js", 111)
|
||||
MustExec(t, "setting up book 2", db, "INSERT INTO books (uuid, label, usn) VALUES (?, ?, ?)", b2UUID, "linux", 122)
|
||||
|
||||
MustExec(t, "setting up note 1", db, "INSERT INTO notes (id, uuid, book_uuid, content, added_on, usn) VALUES (?, ?, ?, ?, ?, ?)", 1, "f0d0fbb7-31ff-45ae-9f0f-4e429c0c797f", b1UUID, "n1 content", 1515199951, 11)
|
||||
MustExec(t, "setting up note 2", db, "INSERT INTO notes (id, uuid, book_uuid, content, added_on, usn) VALUES (?, ?, ?, ?, ?, ?)", 2, "43827b9a-c2b0-4c06-a290-97991c896653", b1UUID, "n2 content", 1515199943, 12)
|
||||
MustExec(t, "setting up note 3", db, "INSERT INTO notes (id, uuid, book_uuid, content, added_on, usn) VALUES (?, ?, ?, ?, ?, ?)", 3, "3e065d55-6d47-42f2-a6bf-f5844130b2d2", b2UUID, "n3 content", 1515199961, 13)
|
||||
MustExec(t, "setting up note 1", db, "INSERT INTO notes (uuid, book_uuid, body, added_on, usn) VALUES (?, ?, ?, ?, ?)", "f0d0fbb7-31ff-45ae-9f0f-4e429c0c797f", b1UUID, "n1 body", 1515199951, 11)
|
||||
MustExec(t, "setting up note 2", db, "INSERT INTO notes (uuid, book_uuid, body, added_on, usn) VALUES (?, ?, ?, ?, ?)", "43827b9a-c2b0-4c06-a290-97991c896653", b1UUID, "n2 body", 1515199943, 12)
|
||||
MustExec(t, "setting up note 3", db, "INSERT INTO notes (uuid, book_uuid, body, added_on, usn) VALUES (?, ?, ?, ?, ?)", "3e065d55-6d47-42f2-a6bf-f5844130b2d2", b2UUID, "n3 body", 1515199961, 13)
|
||||
}
|
||||
|
||||
// Setup3 sets up a dnote env #1
|
||||
|
|
@ -44,7 +44,7 @@ func Setup3(t *testing.T, ctx infra.DnoteCtx) {
|
|||
|
||||
MustExec(t, "setting up book 1", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "js")
|
||||
|
||||
MustExec(t, "setting up note 1", db, "INSERT INTO notes (uuid, book_uuid, content, added_on) VALUES (?, ?, ?, ?)", "43827b9a-c2b0-4c06-a290-97991c896653", b1UUID, "Booleans have toString()", 1515199943)
|
||||
MustExec(t, "setting up note 1", db, "INSERT INTO notes (uuid, book_uuid, body, added_on) VALUES (?, ?, ?, ?)", "43827b9a-c2b0-4c06-a290-97991c896653", b1UUID, "Booleans have toString()", 1515199943)
|
||||
}
|
||||
|
||||
// Setup4 sets up a dnote env #1
|
||||
|
|
@ -56,6 +56,6 @@ func Setup4(t *testing.T, ctx infra.DnoteCtx) {
|
|||
|
||||
MustExec(t, "setting up book 1", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "js")
|
||||
|
||||
MustExec(t, "setting up note 1", db, "INSERT INTO notes (id, uuid, book_uuid, content, added_on) VALUES (?, ?, ?, ?, ?)", 1, "43827b9a-c2b0-4c06-a290-97991c896653", b1UUID, "Booleans have toString()", 1515199943)
|
||||
MustExec(t, "setting up note 2", db, "INSERT INTO notes (id, uuid, book_uuid, content, added_on) VALUES (?, ?, ?, ?, ?)", 2, "f0d0fbb7-31ff-45ae-9f0f-4e429c0c797f", b1UUID, "Date object implements mathematical comparisons", 1515199951)
|
||||
MustExec(t, "setting up note 1", db, "INSERT INTO notes (rowid, uuid, book_uuid, body, added_on) VALUES (?, ?, ?, ?, ?)", 1, "43827b9a-c2b0-4c06-a290-97991c896653", b1UUID, "Booleans have toString()", 1515199943)
|
||||
MustExec(t, "setting up note 2", db, "INSERT INTO notes (rowid, uuid, book_uuid, body, added_on) VALUES (?, ?, ?, ?, ?)", 2, "f0d0fbb7-31ff-45ae-9f0f-4e429c0c797f", b1UUID, "Date object implements mathematical comparisons", 1515199951)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue