Skip to content

Commit 89d9e4c

Browse files
committed
Updated sqobj view code
1 parent 5c48a61 commit 89d9e4c

27 files changed

+1045
-234
lines changed

Makefile

+12-5
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ BUILD_DIR := build
66
PLUGIN_DIR := $(wildcard plugin/*)
77
CMD_DIR := $(filter-out cmd/README.md, $(wildcard cmd/*))
88
SQLITE_MODULE = "github.com/mutablelogic/go-sqlite"
9+
SERVER_MODULE = "github.com/mutablelogic/go-server"
910

1011
# Build flags
1112
BUILD_LD_FLAGS += -X $(SQLITE_MODULE)/pkg/config.GitSource=${SQLITE_MODULE}
@@ -19,17 +20,23 @@ all: clean server plugins cmd
1920

2021
server: dependencies
2122
@echo Build server
22-
@${GO} build -o ${BUILD_DIR}/server ${BUILD_FLAGS} github.com/mutablelogic/go-server/cmd/server
23+
@${GO} build -o ${BUILD_DIR}/server ${BUILD_FLAGS} ${SERVER_MODULE}/cmd/server
2324

2425
plugins: dependencies $(PLUGIN_DIR)
2526
@echo Build plugin httpserver
26-
@${GO} build -buildmode=plugin -o ${BUILD_DIR}/httpserver.plugin ${BUILD_FLAGS} github.com/mutablelogic/go-server/plugin/httpserver
27+
@${GO} build -buildmode=plugin -o ${BUILD_DIR}/httpserver.plugin ${BUILD_FLAGS} ${SERVER_MODULE}/plugin/httpserver
2728
@echo Build plugin log
28-
@${GO} build -buildmode=plugin -o ${BUILD_DIR}/log.plugin ${BUILD_FLAGS} github.com/mutablelogic/go-server/plugin/log
29+
@${GO} build -buildmode=plugin -o ${BUILD_DIR}/log.plugin ${BUILD_FLAGS} ${SERVER_MODULE}/plugin/log
2930
@echo Build plugin env
30-
@${GO} build -buildmode=plugin -o ${BUILD_DIR}/env.plugin ${BUILD_FLAGS} github.com/mutablelogic/go-server/plugin/env
31+
@${GO} build -buildmode=plugin -o ${BUILD_DIR}/env.plugin ${BUILD_FLAGS} ${SERVER_MODULE}/plugin/env
3132
@echo Build plugin static
32-
@${GO} build -buildmode=plugin -o ${BUILD_DIR}/static.plugin ${BUILD_FLAGS} github.com/mutablelogic/go-server/plugin/static
33+
@${GO} build -buildmode=plugin -o ${BUILD_DIR}/static.plugin ${BUILD_FLAGS} ${SERVER_MODULE}/plugin/static
34+
@echo Build plugin renderer
35+
@${GO} build -buildmode=plugin -o ${BUILD_DIR}/renderer.plugin ${BUILD_FLAGS} ${SERVER_MODULE}/plugin/renderer
36+
@echo Build plugin text-renderer
37+
@${GO} build -buildmode=plugin -o ${BUILD_DIR}/text-renderer.plugin ${BUILD_FLAGS} ${SERVER_MODULE}/plugin/text-renderer
38+
@echo Build plugin markdown-renderer
39+
@${GO} build -buildmode=plugin -o ${BUILD_DIR}/markdown-renderer.plugin ${BUILD_FLAGS} ${SERVER_MODULE}/plugin/markdown-renderer
3340

3441
cmd: dependencies $(CMD_DIR)
3542

deps.go

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package sqlite
2+
3+
// Add additional indirect dependencies here which are required
4+
// when building the server
5+
import (
6+
_ "github.com/gomarkdown/markdown"
7+
_ "github.com/zyedidia/highlight"
8+
)

etc/server.yaml

+12-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ plugins:
44
- build/log.plugin
55
- build/env.plugin
66
- build/sqlite3.plugin
7+
- build/renderer.plugin
78
- build/indexer.plugin
9+
- build/text-renderer.plugin
10+
- build/markdown-renderer.plugin
811

912
# HTTP Server parameters
1013
httpserver:
@@ -39,12 +42,18 @@ sqlite3:
3942

4043
# Set trace to true to enable the ability to profile queries. Profiling information
4144
# can be displayed through the API.
42-
trace: false
45+
trace: true
4346

4447
# Set max number of connections that can be simultaneously opened
4548
max: 100
4649

4750
indexer:
48-
workers: 2
4951
index:
50-
home: /Volumes/Scratch/Downloads
52+
docs: /opt/go-server/docs
53+
templates: /opt/go-server/templates
54+
tv: /home/djt/media/TV
55+
56+
renderer:
57+
plugins:
58+
- text-renderer
59+
- markdown-renderer

go.mod

+3
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ replace github.com/zyedidia/highlight => github.com/djthorpe/highlight v0.0.0-20
77
require (
88
github.com/djthorpe/go-errors v1.0.2
99
github.com/djthorpe/go-marshaler v0.0.15
10+
github.com/gomarkdown/markdown v0.0.0-20210918233619-6c1113f12c4a
1011
github.com/hashicorp/go-multierror v1.1.1
1112
github.com/mutablelogic/go-server v1.0.39
1213
github.com/rjeczalik/notify v0.9.2
1314
github.com/xuri/excelize/v2 v2.4.1
15+
github.com/zyedidia/highlight v0.0.0-00010101000000-000000000000
1416
golang.org/x/text v0.3.7
1517
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
1618
)
@@ -24,4 +26,5 @@ require (
2426
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect
2527
golang.org/x/net v0.0.0-20210929193557-e81a3d93ecf6 // indirect
2628
golang.org/x/sys v0.0.0-20210930141918-969570ce7c6c // indirect
29+
gopkg.in/yaml.v2 v2.4.0 // indirect
2730
)

go.sum

+3
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ github.com/djthorpe/go-errors v1.0.2 h1:kZuNLhb6Yo1iNHaenGa9s5CpRbOG6KxbUtrME4Lr
88
github.com/djthorpe/go-errors v1.0.2/go.mod h1:HtfrZnMd6HsX75Mtbv9Qcnn0BqOrrFArvCaj3RMnZhY=
99
github.com/djthorpe/go-marshaler v0.0.15 h1:ZXq5YHCsbREbbYJtc0ie9hz7HJ7vIeeDlMbe7cGh0C0=
1010
github.com/djthorpe/go-marshaler v0.0.15/go.mod h1:xCXhTzj52UL3YStRsqUSfrKses7ofmfTXYQfVedn8Lw=
11+
github.com/djthorpe/highlight v0.0.0-20211010083339-d90b2f7f5bae h1:BT6oQ87cEvOxDwDVNhckkHh5BY6fptmBL/Q9wcitNNM=
1112
github.com/djthorpe/highlight v0.0.0-20211010083339-d90b2f7f5bae/go.mod h1:xwWgaGQyllDeATTozVXCqxRv2CZTkDOwYxXUL1dUIf8=
1213
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
1314
github.com/go-asn1-ber/asn1-ber v1.5.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
1415
github.com/go-asn1-ber/asn1-ber v1.5.3/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
1516
github.com/go-ldap/ldap/v3 v3.4.1/go.mod h1:iYS1MdmrmceOJ1QOTnRXrIs7i3kloqtmGQjRvjKpyMg=
17+
github.com/gomarkdown/markdown v0.0.0-20210918233619-6c1113f12c4a h1:syEwbl3pF5Y1mnIStrPwqd50vNU1AAKuAy8HFCPAgUc=
1618
github.com/gomarkdown/markdown v0.0.0-20210918233619-6c1113f12c4a/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA=
1719
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
1820
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
@@ -82,6 +84,7 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
8284
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
8385
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
8486
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
87+
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
8588
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
8689
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
8790
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=

pkg/indexer/queue.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ func (q *Queue) add(e EventType, name, path string, info fs.FileInfo) {
157157
// This assumes the key does not exist
158158
key := key(name, path)
159159
if _, exists := q.k[key]; exists {
160-
panic("Queue: key already exists")
160+
panic("Queue: key already exists, " + key)
161161
}
162162
q.q = append(q.q, key)
163163
q.k[key] = &QueueEvent{e, name, path, info}

pkg/indexer/schema.go

+94-63
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,57 @@ import (
44
"context"
55
"io"
66
"path/filepath"
7+
"reflect"
8+
"time"
9+
10+
// Package imports
11+
sqobj "github.com/mutablelogic/go-sqlite/pkg/sqobj"
712

813
// Namespace imports
914
. "github.com/mutablelogic/go-sqlite"
1015
. "github.com/mutablelogic/go-sqlite/pkg/lang"
1116
. "github.com/mutablelogic/go-sqlite/pkg/quote"
1217
)
1318

19+
///////////////////////////////////////////////////////////////////////////////
20+
// Types
21+
22+
type File struct {
23+
Name string `sqlite:"name,primary,index:name"` // Index name, primary key
24+
Path string `sqlite:"path,primary,index:path"` // Relative path, primary key
25+
Parent string `sqlite:"parent,index:parent"` // Parent folder
26+
Filename string `sqlite:"filename,notnull,index:filename"` // Filename
27+
IsDir bool `sqlite:"isdir,notnull"` // Is a directory
28+
Ext string `sqlite:"ext,index:ext"`
29+
ModTime time.Time `sqlite:"modtime"`
30+
Size int64 `sqlite:"size"`
31+
}
32+
33+
type Doc struct {
34+
Name string `sqlite:"name,primary,foreign"` // Index name, primary key
35+
Path string `sqlite:"path,primary,foreign"` // Relative path, primary key
36+
Title string `sqlite:"title,notnull"` // Title of the document, text
37+
Description string `sqlite:"description"` // Description of the document, text
38+
Shortform string `sqlite:"shortform"` // Shortform of the document, html
39+
}
40+
41+
type Search struct {
42+
Name string `sqlite:"name"`
43+
Parent string `sqlite:"parent"`
44+
Filename string `sqlite:"filename"`
45+
//Title string `sqlite:"title"`
46+
//Description string `sqlite:"description"`
47+
//Shortform string `sqlite:"shortform"`
48+
//Text string `sqlite:"text"`
49+
}
50+
1451
///////////////////////////////////////////////////////////////////////////////
1552
// GLOBALS
1653

1754
const (
18-
filesTableName = "file"
19-
nameIndexName = "file_name"
55+
fileTableName = "file"
2056
searchTableName = "search"
21-
parentIndexName = "file_parent"
22-
filenameIndexName = "file_filename"
23-
extIndexName = "file_filename"
57+
docTableName = "doc"
2458
searchTriggerInsertName = "search_insert"
2559
searchTriggerDeleteName = "search_delete"
2660
searchTriggerUpdateName = "search_update"
@@ -30,6 +64,25 @@ const (
3064
defaultTokenizer = "porter unicode61"
3165
)
3266

67+
var (
68+
filesTypeCast = []reflect.Type{
69+
reflect.TypeOf(""),
70+
reflect.TypeOf(""),
71+
reflect.TypeOf(""),
72+
reflect.TypeOf(""),
73+
reflect.TypeOf(false),
74+
reflect.TypeOf(""),
75+
reflect.TypeOf(time.Time{}),
76+
reflect.TypeOf(int64(0)),
77+
}
78+
)
79+
80+
var (
81+
fileTable = sqobj.MustRegisterClass(N(fileTableName), File{})
82+
docTable = sqobj.MustRegisterClass(N(docTableName), Doc{}).ForeignKey(fileTable)
83+
searchTable = sqobj.MustRegisterVirtual(N(searchTableName), "fts5", Search{}, "content="+Quote(fileTableName))
84+
)
85+
3386
///////////////////////////////////////////////////////////////////////////////
3487
// PUBLIC METHODS
3588

@@ -41,64 +94,28 @@ func CreateSchema(ctx context.Context, conn SQConnection, schema string, tokeniz
4194

4295
// Create tables
4396
return conn.Do(ctx, 0, func(txn SQTransaction) error {
44-
if _, err := txn.Query(N(filesTableName).WithSchema(schema).CreateTable(
45-
C("name").WithPrimary(),
46-
C("path").WithPrimary(),
47-
C("parent"),
48-
C("filename").NotNull(),
49-
C("isdir").WithType("INTEGER").NotNull(),
50-
C("ext"),
51-
C("modtime"),
52-
C("size").WithType("INTEGER"),
53-
).IfNotExists()); err != nil {
54-
return err
55-
}
56-
// Create the file indexes
57-
if _, err := txn.Query(N(nameIndexName).WithSchema(schema).CreateIndex(
58-
filesTableName, "name",
59-
).IfNotExists()); err != nil {
60-
return err
61-
}
62-
if _, err := txn.Query(N(parentIndexName).WithSchema(schema).CreateIndex(
63-
filesTableName, "parent",
64-
).IfNotExists()); err != nil {
65-
return err
66-
}
67-
if _, err := txn.Query(N(filenameIndexName).WithSchema(schema).CreateIndex(
68-
filesTableName, "filename",
69-
).IfNotExists()); err != nil {
70-
return err
97+
if err := fileTable.Create(txn, schema); err != nil {
98+
return nil
7199
}
72-
if _, err := txn.Query(N(extIndexName).WithSchema(schema).CreateIndex(
73-
filesTableName, "ext",
74-
).IfNotExists()); err != nil {
75-
return err
100+
if err := docTable.Create(txn, schema); err != nil {
101+
return nil
76102
}
77-
// Create the search table
78-
if _, err := txn.Query(N(searchTableName).WithSchema(schema).CreateVirtualTable(
79-
"fts5",
80-
"name",
81-
"parent",
82-
"filename",
83-
).Options(
84-
"content="+filesTableName,
85-
"tokenize="+Quote(tokenizer),
86-
).IfNotExists()); err != nil {
87-
return err
103+
if err := searchTable.Create(txn, schema, "tokenize="+Quote(tokenizer)); err != nil {
104+
return nil
88105
}
89106
// triggers to keep the FTS index up to date
90107
// https://www.sqlite.org/fts5.html
91-
if _, err := txn.Query(N(searchTriggerInsertName).WithSchema(schema).CreateTrigger(filesTableName,
108+
if _, err := txn.Query(N(searchTriggerInsertName).WithSchema(schema).CreateTrigger(fileTableName,
92109
Q("INSERT INTO ", searchTableName, " (rowid, name, parent, filename) VALUES (new.rowid, new.name, new.parent, new.filename)"),
93110
).After().Insert().IfNotExists()); err != nil {
94111
return err
95112
}
96-
if _, err := txn.Query(N(searchTriggerDeleteName).WithSchema(schema).CreateTrigger(filesTableName,
113+
if _, err := txn.Query(N(searchTriggerDeleteName).WithSchema(schema).CreateTrigger(fileTableName,
97114
Q("INSERT INTO ", searchTableName, " (", searchTableName, ", rowid, name, parent, filename) VALUES ('delete', old.rowid, old.name, old.parent, old.filename)"),
98115
).After().Delete().IfNotExists()); err != nil {
99116
return err
100117
}
101-
if _, err := txn.Query(N(searchTriggerUpdateName).WithSchema(schema).CreateTrigger(filesTableName,
118+
if _, err := txn.Query(N(searchTriggerUpdateName).WithSchema(schema).CreateTrigger(fileTableName,
102119
Q("INSERT INTO ", searchTableName, " (", searchTableName, ", rowid, name, parent, filename) VALUES ('delete', old.rowid, old.name, old.parent, old.filename)"),
103120
Q("INSERT INTO ", searchTableName, " (rowid, name, parent, filename) VALUES (new.rowid, new.name, new.parent, new.filename)"),
104121
).After().Update().IfNotExists()); err != nil {
@@ -112,7 +129,7 @@ func CreateSchema(ctx context.Context, conn SQConnection, schema string, tokeniz
112129
func ListIndexWithCount(ctx context.Context, conn SQConnection, schema string) (map[string]int64, error) {
113130
results := make(map[string]int64)
114131
if err := conn.Do(ctx, 0, func(txn SQTransaction) error {
115-
s := Q("SELECT name,COUNT(*) AS count FROM ", N(filesTableName).WithSchema(schema), " GROUP BY name")
132+
s := Q("SELECT name,COUNT(*) AS count FROM ", N(fileTableName).WithSchema(schema), " GROUP BY name")
116133
r, err := txn.Query(s)
117134
if err != nil && err != io.EOF {
118135
return err
@@ -136,7 +153,7 @@ func ListIndexWithCount(ctx context.Context, conn SQConnection, schema string) (
136153
}
137154

138155
func Replace(schema string, evt *QueueEvent) (SQStatement, []interface{}) {
139-
return N(filesTableName).WithSchema(schema).Insert(
156+
return N(fileTableName).WithSchema(schema).Insert(
140157
"name", "path", "parent", "filename", "isdir", "ext", "modtime", "size",
141158
).WithConflictUpdate("name", "path"),
142159
[]interface{}{
@@ -152,16 +169,30 @@ func Replace(schema string, evt *QueueEvent) (SQStatement, []interface{}) {
152169
}
153170

154171
func Delete(schema string, evt *QueueEvent) (SQStatement, []interface{}) {
155-
return N(filesTableName).WithSchema(schema).Delete(Q("name=?"), Q("path=?")),
172+
return N(fileTableName).WithSchema(schema).Delete(Q("name=?"), Q("path=?")),
156173
[]interface{}{evt.Name, evt.Path}
157174
}
158175

176+
func GetFile(schema string, rowid int64) (SQStatement, []interface{}, []reflect.Type) {
177+
return S(N(fileTableName).WithSchema(schema)).
178+
To(N("name"), N("path"), N("parent"), N("filename"), N("isdir"), N("ext"), N("modtime"), N("size")).
179+
Where(Q("rowid", "=", P)), []interface{}{rowid}, filesTypeCast
180+
}
181+
182+
func UpsertDoc(txn SQTransaction, doc *Doc) (int64, error) {
183+
if n, err := docTable.UpsertKeys(txn, doc); err != nil {
184+
return 0, err
185+
} else {
186+
return n[0], nil
187+
}
188+
}
189+
159190
func Query(schema string, snippet bool) SQSelect {
160191
// Set the query join
161192
queryJoin := J(
162193
N(searchTableName).WithSchema(schema),
163-
N(filesTableName).WithSchema(schema),
164-
).LeftJoin(Q(N(searchTableName), ".rowid=", N(filesTableName), ".rowid"))
194+
N(fileTableName).WithSchema(schema),
195+
).LeftJoin(Q(N(searchTableName), ".rowid=", N(fileTableName), ".rowid"))
165196
// Set the snippet expression
166197
snippetExpr := V("")
167198
if snippet {
@@ -172,13 +203,13 @@ func Query(schema string, snippet bool) SQSelect {
172203
N("rowid").WithSchema(searchTableName),
173204
N("rank").WithSchema(searchTableName),
174205
snippetExpr,
175-
N("name").WithSchema(filesTableName),
176-
N("path").WithSchema(filesTableName),
177-
N("parent").WithSchema(filesTableName),
178-
N("filename").WithSchema(filesTableName),
179-
N("isdir").WithSchema(filesTableName),
180-
N("ext").WithSchema(filesTableName),
181-
N("modtime").WithSchema(filesTableName),
182-
N("size").WithSchema(filesTableName),
206+
N("name").WithSchema(fileTableName),
207+
N("path").WithSchema(fileTableName),
208+
N("parent").WithSchema(fileTableName),
209+
N("filename").WithSchema(fileTableName),
210+
N("isdir").WithSchema(fileTableName),
211+
N("ext").WithSchema(fileTableName),
212+
N("modtime").WithSchema(fileTableName),
213+
N("size").WithSchema(fileTableName),
183214
).Where(Q(searchTableName, " MATCH ", P)).Order(N("rank"))
184215
}

0 commit comments

Comments
 (0)