1diff --git a/cmd/dict/main.go b/cmd/dict/main.go
2index 09e9412599a4f1d86d1348570f7abec66e36fd6c..5bd60961e253fce4164294ee8db575dbec452b89 100644
3--- a/cmd/dict/main.go
4+++ b/cmd/dict/main.go
5@@ -7,6 +7,7 @@
6 "github.com/urfave/cli/v2"
7
8 "git.gabrielgio.me/dict/cmd/importer"
9+ "git.gabrielgio.me/dict/cmd/server"
10 "git.gabrielgio.me/dict/cmd/ui"
11 )
12
13@@ -17,6 +18,7 @@ Usage: "interactive dictionary",
14 Commands: []*cli.Command{
15 importer.ImportCommand,
16 ui.UICommand,
17+ server.ServeCommand,
18 },
19 }
20
21diff --git a/cmd/server/server.go b/cmd/server/server.go
22new file mode 100644
23index 0000000000000000000000000000000000000000..a0de54712bf0f32a79e990fee1ceab4796f21abf
24--- /dev/null
25+++ b/cmd/server/server.go
26@@ -0,0 +1,96 @@
27+package server
28+
29+import (
30+ "context"
31+ "fmt"
32+ "io"
33+ "log/slog"
34+ "net"
35+ "strings"
36+
37+ "git.gabrielgio.me/dict/db"
38+ "github.com/urfave/cli/v2"
39+)
40+
41+var ServeCommand = &cli.Command{
42+ Name: "serve",
43+ Usage: "Start a simple tcp server to ansower queries",
44+ Flags: []cli.Flag{
45+ &cli.StringFlag{
46+ Name: "addr",
47+ Value: "/tmp/dict.sock",
48+ Usage: "Address",
49+ },
50+ &cli.StringFlag{
51+ Name: "database",
52+ Value: "main.dict",
53+ Usage: "Dictionary database location",
54+ },
55+ },
56+ Action: func(cCtx *cli.Context) error {
57+ addr := cCtx.String("addr")
58+ database := cCtx.String("database")
59+ return Server(context.Background(), addr, database)
60+ },
61+}
62+
63+func Server(ctx context.Context, addr, database string) error {
64+ // Listen for incoming connections on port 8080
65+ db, err := db.Open(database)
66+ if err != nil {
67+ return fmt.Errorf("Error openning datbase:%w", err)
68+ }
69+
70+ ln, err := net.Listen("unix", addr)
71+ if err != nil {
72+ return err
73+ }
74+
75+ defer ln.Close()
76+
77+ // Accept incoming connections and handle them
78+ for {
79+ conn, err := ln.Accept()
80+ if err != nil {
81+ slog.Error("Error accepting conn", "error", err)
82+ continue
83+ }
84+
85+ slog.Info("Connection accepeted")
86+ go handleConnection(conn, db)
87+ }
88+}
89+
90+func handleConnection(conn net.Conn, db *db.DB) {
91+ defer conn.Close()
92+
93+ // Read incoming data
94+ buf := make([]byte, 0, 4096) // big buffer
95+ tmp := make([]byte, 256) // using small tmo buffer for demonstrating
96+ for {
97+ n, err := conn.Read(tmp)
98+ if err != nil {
99+ if err != io.EOF {
100+ slog.Error("Error reading conn", "error", err)
101+ return
102+ }
103+ break
104+ }
105+ buf = append(buf, tmp[:n]...)
106+
107+ }
108+
109+ q := strings.ReplaceAll(string(buf), "\n", "")
110+
111+ slog.Info("Query", "query", q)
112+ ws, err := db.SelectDict(context.Background(), q, 10)
113+ if err != nil {
114+ slog.Error("Error selecting", "error", err)
115+ return
116+ }
117+
118+ slog.Info("Count", "q", len(ws))
119+ for _, w := range ws {
120+ fmt.Fprintf(conn, "%s\n%s\n\n", w.Word, w.Line)
121+ }
122+}
123diff --git a/db/db.go b/db/db.go
124index b28dea2cb1aa9b02df7b1ab68295f21e6f36458e..61f3bb5c2d8240e651ca80c8ff127201c7b965bc 100644
125--- a/db/db.go
126+++ b/db/db.go
127@@ -56,7 +56,8 @@ `SELECT
128 word, line
129 FROM words
130 WHERE word MATCH ?
131- ORDER BY rank;`,
132+ ORDER BY rank
133+ LIMIT ?;`,
134 query, limit,
135 )
136 if err != nil {