From b1f41bef6434baa646da97e39462a32209abf8ee Mon Sep 17 00:00:00 2001 From: SchoolyB Date: Thu, 13 Nov 2025 06:32:35 -0600 Subject: [PATCH 1/9] chore: add gitignore --- .gitignore | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..56a03de --- /dev/null +++ b/.gitignore @@ -0,0 +1,43 @@ +# Compiled binaries +*.bin +*.so +*.dylib +*.exe +*.log +*.logs +bin/logs/ + +# Environment files +.env +.env.local +.env.*.local + +# Bin directory exclusions +bin/*.bin +bin/main.bin +bin/.env +bin/projects/ +bin/project.json +bin/backups/ +bin/collections/ +bin/temp/ +bin/logs/ +bin/tmp/ +bin/system/ + + +# Allow specific Go and Odin source files +!main/main.odin +# Exclude Go module files if not needed +go.sum +go.mod + +# System and IDE files +.DS_Store +.ropeproject +*.key +*.ostrichdb +*project.json +*.claude +*rate_limits +*requests.json \ No newline at end of file From abfb75ae9f57b8efbb08a8e558b221eca8d61524 Mon Sep 17 00:00:00 2001 From: SchoolyB Date: Thu, 13 Nov 2025 07:28:11 -0600 Subject: [PATCH 2/9] add: Ostrichdb-go sdk & open-ostrichdb backend --- OstrichDB | 1 + client/client.go | 2 +- client/go.mod | 5 +++-- client/go.sum | 2 ++ main/main.go | 31 +++++++++++++++++++++++++++++++ ostrichdb-go | 1 + 6 files changed, 39 insertions(+), 3 deletions(-) create mode 160000 OstrichDB create mode 100644 main/main.go create mode 160000 ostrichdb-go diff --git a/OstrichDB b/OstrichDB new file mode 160000 index 0000000..2488c23 --- /dev/null +++ b/OstrichDB @@ -0,0 +1 @@ +Subproject commit 2488c23979d0a346156c3d2423bee96bc98fda44 diff --git a/client/client.go b/client/client.go index a624a72..3720521 100644 --- a/client/client.go +++ b/client/client.go @@ -1,4 +1,4 @@ -package main +package client import ( "bufio" diff --git a/client/go.mod b/client/go.mod index 6d4dd4e..e8d7eb6 100644 --- a/client/go.mod +++ b/client/go.mod @@ -1,10 +1,11 @@ -module twix-client +module client go 1.25.3 +require github.com/charmbracelet/bubbletea v1.3.10 + require ( github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect - github.com/charmbracelet/bubbletea v1.3.10 // indirect github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect github.com/charmbracelet/lipgloss v1.1.0 // indirect github.com/charmbracelet/x/ansi v0.10.1 // indirect diff --git a/client/go.sum b/client/go.sum index cc7a40a..4789639 100644 --- a/client/go.sum +++ b/client/go.sum @@ -33,6 +33,8 @@ github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= +golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E= +golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= diff --git a/main/main.go b/main/main.go new file mode 100644 index 0000000..89a0b20 --- /dev/null +++ b/main/main.go @@ -0,0 +1,31 @@ +package main + +import ( + "fmt" + + // c "client" //uncomment when ready to use client functions + sdk "ostrichdb-go/src/sdk" +) + +func main (){ + + config:= sdk.NewConfigBuilder() + client:= sdk.NewClientBuilder(config) + + project:= sdk.NewProjectBuilder(client, "twix") + projectErr:= sdk.CreateProject(project) + if projectErr != nil { + + fmt.Println("Error creating project") + fmt.Println(projectErr) + } + + //Note: Whenever implementing user auth on client please replace "Marshall" with username input + collection:= sdk.NewCollectionBuilder(project, "Marshall") + collectionErr:= sdk.CreateCollection(collection) + + if collectionErr != nil { + fmt.Println("Error creating collection") + } + +} \ No newline at end of file diff --git a/ostrichdb-go b/ostrichdb-go new file mode 160000 index 0000000..382ced8 --- /dev/null +++ b/ostrichdb-go @@ -0,0 +1 @@ +Subproject commit 382ced89c16d87959a7b9b057d8c30b66c136816 From e89447ea862bff54c7c2077e8ed5aa28665f9d7c Mon Sep 17 00:00:00 2001 From: SchoolyB Date: Fri, 14 Nov 2025 08:37:47 -0600 Subject: [PATCH 3/9] chore: update main/add helpers for creating post name --- main/main.go | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/main/main.go b/main/main.go index 89a0b20..1b3972c 100644 --- a/main/main.go +++ b/main/main.go @@ -4,11 +4,11 @@ import ( "fmt" // c "client" //uncomment when ready to use client functions + "ostrichdb-go/src/lib" sdk "ostrichdb-go/src/sdk" ) func main (){ - config:= sdk.NewConfigBuilder() client:= sdk.NewClientBuilder(config) @@ -28,4 +28,26 @@ func main (){ fmt.Println("Error creating collection") } + + //Any time the user creates a Post, a new cluster will be created + newPostName:=create_post_name(collection) + cluster:= sdk.NewClusterBuilder(project, collection, newPostName) + sdk.CreateCluster(cluster) + +} + + +//Helper functions for client will move later - Marshalla +func increment_post_count(collection *lib.Collection) int{ + currentCount:= sdk.GetClusterCount(collection) + incremented := currentCount + 1 + return incremented +} + + +//Only used to create a name for the post within OstrichDB e.g Post1, Post2, etc +func create_post_name(collection *lib.Collection) string{ + postCount:= increment_post_count(collection) + postName:= fmt.Sprintf("Post%d", postCount) + return postName } \ No newline at end of file From d9c52b460a50942881d060704f3aa6c97f78795f Mon Sep 17 00:00:00 2001 From: SchoolyB Date: Fri, 14 Nov 2025 23:17:33 -0600 Subject: [PATCH 4/9] chore: clean project structure/successful Twix post to OstrichDB --- client/client.go | 114 ----------------- client/go.mod | 26 ---- client/go.sum | 43 ------- main/main.go | 56 +++----- server/go.mod | 3 - server/main.go | 149 --------------------- src/client/client.go | 292 ++++++++++++++++++++++++++++++++++++++++++ src/client/helpers.go | 23 ++++ src/client/posts.go | 30 +++++ src/library/types.go | 1 + src/server/main.go | 52 ++++++++ 11 files changed, 419 insertions(+), 370 deletions(-) delete mode 100644 client/client.go delete mode 100644 client/go.mod delete mode 100644 client/go.sum delete mode 100644 server/go.mod delete mode 100644 server/main.go create mode 100644 src/client/client.go create mode 100644 src/client/helpers.go create mode 100644 src/client/posts.go create mode 100644 src/library/types.go create mode 100644 src/server/main.go diff --git a/client/client.go b/client/client.go deleted file mode 100644 index 3720521..0000000 --- a/client/client.go +++ /dev/null @@ -1,114 +0,0 @@ -package client - -import ( - "bufio" - "fmt" - "log" - "net" - - tea "github.com/charmbracelet/bubbletea" -) - -// "FEED" -func HandleFeed(pageNum int) (string, error) { - conn, _ := net.Dial("tcp", "localhost:8080") - defer conn.Close() - fmt.Fprintf(conn, "FEED %v\n", pageNum) - return bufio.NewReader(conn).ReadString('\n') -} - -// "POST" -func HandlePost(content string) (string, error) { - conn, _ := net.Dial("tcp", "localhost:8080") - defer conn.Close() - fmt.Fprintf(conn, "POST %v\n", content) - return bufio.NewReader(conn).ReadString('\n') -} - -// "FETCH" -func HandleFetch(post string) (string, error) { - conn, _ := net.Dial("tcp", "localhost:8080") - defer conn.Close() - fmt.Fprintf(conn, "FETCH %v\n", post) - return bufio.NewReader(conn).ReadString('\n') -} - -// "COMMENT" -func HandleComment(post, content string) (string, error) { - conn, _ := net.Dial("tcp", "localhost:8080") - defer conn.Close() - fmt.Fprintf(conn, "COMMENT %v %v\n", post, content) - return bufio.NewReader(conn).ReadString('\n') -} - -// "LIKE" -func HandleLike(post string) (string, error) { - conn, _ := net.Dial("tcp", "localhost:8080") - defer conn.Close() - fmt.Fprintf(conn, "LIKE %v\n", post) - return bufio.NewReader(conn).ReadString('\n') -} - -type model struct { - cursor int - width int - height int - text string -} - -func (m model) Init() tea.Cmd { - return nil -} - -func initialModel() model { - return model{ - text: "", - } -} - -func (m model) View() string { - s := fmt.Sprintf("cursor %v\n", m.cursor) - s += fmt.Sprintf("1. cobbcoding\nThis is a post.\n\n") - s += fmt.Sprintf("2. stam\nThis is a post 2.\n\n") - for range m.height - 8 { - s += "\n" - } - s += fmt.Sprintf(":%v|", m.text) - return s -} - -func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - switch msg.(type) { - case tea.KeyMsg: - switch msg.(tea.KeyMsg).String() { - case "ctrl+c": - return m, tea.Quit - case "backspace": - if m.cursor > 0 { - m.cursor-- - m.text = m.text[:m.cursor] - } - break - case "enter": - m.text = "" - m.cursor = 0 - break - default: - m.text += msg.(tea.KeyMsg).String() - m.cursor += 1 - } - case tea.WindowSizeMsg: - m.width = msg.(tea.WindowSizeMsg).Width - m.height = msg.(tea.WindowSizeMsg).Height - break - } - return m, nil -} - -func main() { - p := tea.NewProgram(initialModel(), tea.WithAltScreen()) - _, err := p.Run() - if err != nil { - log.Fatal("Could not start TUI") - } -} diff --git a/client/go.mod b/client/go.mod deleted file mode 100644 index e8d7eb6..0000000 --- a/client/go.mod +++ /dev/null @@ -1,26 +0,0 @@ -module client - -go 1.25.3 - -require github.com/charmbracelet/bubbletea v1.3.10 - -require ( - github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect - github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect - github.com/charmbracelet/lipgloss v1.1.0 // indirect - github.com/charmbracelet/x/ansi v0.10.1 // indirect - github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect - github.com/charmbracelet/x/term v0.2.1 // indirect - github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect - github.com/lucasb-eyer/go-colorful v1.2.0 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-localereader v0.0.1 // indirect - github.com/mattn/go-runewidth v0.0.16 // indirect - github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect - github.com/muesli/cancelreader v0.2.2 // indirect - github.com/muesli/termenv v0.16.0 // indirect - github.com/rivo/uniseg v0.4.7 // indirect - github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect - golang.org/x/sys v0.36.0 // indirect - golang.org/x/text v0.3.8 // indirect -) diff --git a/client/go.sum b/client/go.sum deleted file mode 100644 index 4789639..0000000 --- a/client/go.sum +++ /dev/null @@ -1,43 +0,0 @@ -github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= -github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= -github.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlvF9nRvCICw= -github.com/charmbracelet/bubbletea v1.3.10/go.mod h1:ORQfo0fk8U+po9VaNvnV95UPWA1BitP1E0N6xJPlHr4= -github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs= -github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk= -github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY= -github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30= -github.com/charmbracelet/x/ansi v0.10.1 h1:rL3Koar5XvX0pHGfovN03f5cxLbCF2YvLeyz7D2jVDQ= -github.com/charmbracelet/x/ansi v0.10.1/go.mod h1:3RQDQ6lDnROptfpWuUVIUG64bD2g2BgntdxH0Ya5TeE= -github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd h1:vy0GVL4jeHEwG5YOXDmi86oYw2yuYUGqz6a8sLwg0X8= -github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs= -github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ= -github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg= -github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4= -github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM= -github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= -github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= -github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88= -github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= -github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI= -github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo= -github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= -github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= -github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc= -github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= -github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= -github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= -github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= -golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E= -golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= -golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= -golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= diff --git a/main/main.go b/main/main.go index 1b3972c..a8eb4b2 100644 --- a/main/main.go +++ b/main/main.go @@ -1,53 +1,39 @@ package main import ( - "fmt" - - // c "client" //uncomment when ready to use client functions + c "client" //uncomment when ready to use client functions + // "fmt" "ostrichdb-go/src/lib" sdk "ostrichdb-go/src/sdk" ) +var config lib.Config = *sdk.NewConfigBuilder() +var client lib.Client = *sdk.NewClientBuilder(&config) +var project lib.Project = *sdk.NewProjectBuilder(&client, "twix") -func main (){ - config:= sdk.NewConfigBuilder() - client:= sdk.NewClientBuilder(config) - project:= sdk.NewProjectBuilder(client, "twix") - projectErr:= sdk.CreateProject(project) - if projectErr != nil { +func main (){ - fmt.Println("Error creating project") - fmt.Println(projectErr) - } + // projectErr:= sdk.CreateProject(&project) + // if projectErr != nil { + // fmt.Println("Error creating project") + // fmt.Println(projectErr) + // } //Note: Whenever implementing user auth on client please replace "Marshall" with username input - collection:= sdk.NewCollectionBuilder(project, "Marshall") - collectionErr:= sdk.CreateCollection(collection) + collection:= sdk.NewCollectionBuilder(&project, "Marshall") + // collectionErr:= sdk.CreateCollection(collection) - if collectionErr != nil { - fmt.Println("Error creating collection") - } + // if collectionErr != nil { + // fmt.Println("Error creating collection") + // } + //Testing things out + currentUser:= c.NewUserBuilder("@Marshall") + newPost:= c.NewPostBuilder(¤tUser, "Hello World") + c.HandlePost(project, *collection, newPost) - //Any time the user creates a Post, a new cluster will be created - newPostName:=create_post_name(collection) - cluster:= sdk.NewClusterBuilder(project, collection, newPostName) - sdk.CreateCluster(cluster) - -} + // c.Run() -//Helper functions for client will move later - Marshalla -func increment_post_count(collection *lib.Collection) int{ - currentCount:= sdk.GetClusterCount(collection) - incremented := currentCount + 1 - return incremented } - -//Only used to create a name for the post within OstrichDB e.g Post1, Post2, etc -func create_post_name(collection *lib.Collection) string{ - postCount:= increment_post_count(collection) - postName:= fmt.Sprintf("Post%d", postCount) - return postName -} \ No newline at end of file diff --git a/server/go.mod b/server/go.mod deleted file mode 100644 index bc30072..0000000 --- a/server/go.mod +++ /dev/null @@ -1,3 +0,0 @@ -module twix - -go 1.25.3 diff --git a/server/main.go b/server/main.go deleted file mode 100644 index 7281793..0000000 --- a/server/main.go +++ /dev/null @@ -1,149 +0,0 @@ -package main - -import ( - "bufio" - "fmt" - "log" - "net" - "strconv" - "strings" -) - -const ( - PORT = ":8080" -) - -type Post struct { - id uint64 - content string - author string - likes uint64 - comments []Post -} - -var posts []Post - -func handleConnection(conn net.Conn) { - defer conn.Close() - msg, err := bufio.NewReader(conn).ReadString('\n') - if err != nil { - fmt.Println("Could not read message from connection: ", err) - return - } - res, ok := parseCommand(msg) - if !ok { - conn.Write([]byte("Could not parse message...\n")) - return - } - conn.Write([]byte(res)) -} - -func parsePostId(id_s string) *Post { - ids := strings.Split(id_s, "-") - id, err := strconv.Atoi(ids[0]) - if err != nil { - fmt.Println("Could not convert to integer: ", ids[0]) - return nil - } - if id >= len(posts) { - fmt.Printf("Post %v does not exist\n", id) - return nil - } - cur_post := &posts[id] - for id_i := 1; id_i < len(ids); id_i += 1 { - id := ids[id_i] - id_val, err := strconv.Atoi(id) - if err != nil { - fmt.Println("Could not convert to integer: ", id) - return nil - } - if id_val >= len(cur_post.comments) { - fmt.Printf("Post %v does not exist\n", id_val) - return nil - } - cur_post = &cur_post.comments[id_val] - } - return cur_post -} - -func parseCommand(command string) (string, bool) { - words := strings.Fields(command) - var res string - if len(words) < 2 { - fmt.Println("Not a valid command") - return "", false - } - switch words[0] { - // example: POST - case "POST": - msg := strings.Join(words[1:], " ") - post := Post{id: uint64(len(posts)), content: msg} - posts = append(posts, post) - res = "Post created successfully..." - break - // example: FEED - case "FEED": - res = fmt.Sprintf(res, "%v", posts) - break - // example: FETCH - case "FETCH": - if len(words) < 2 { - fmt.Println("Not enough arguments to command ", words[0]) - return "", false - } - post := parsePostId(words[1]) - if post == nil { - fmt.Println("Could not parse ", words[1]) - return "", false - } - res = fmt.Sprintf(res, "%v", post) - break - // example: COMMENT - case "COMMENT": - if len(words) < 3 { - fmt.Println("Not enough arguments to command ", words[0]) - return "", false - } - msg := strings.Join(words[2:], " ") - post := parsePostId(words[1]) - if post == nil { - fmt.Println("Could not parse ", words[1]) - return "", false - } - fmt.Println(post) - comment := Post{id: uint64(len(post.comments)), content: msg} - post.comments = append(post.comments, comment) - res = "Comment posted successfully..." - break - // example: LIKE - case "LIKE": - post := parsePostId(words[1]) - if post == nil { - fmt.Println("Could not parse ", words[1]) - return "", false - } - post.likes += 1 - res = "Post liked successfully..." - break - default: - log.Fatalf("Unknown command: %s\n", words[0]) - } - return res, true -} - -func main() { - list, err := net.Listen("tcp", PORT) - if err != nil { - log.Fatalf("Could not start server: %s\n", err) - } - defer list.Close() - fmt.Printf("Now accepting connections on port %v...\n", PORT) - for { - conn, err := list.Accept() - if err != nil { - fmt.Println("Could not accept incoming request: ", err) - continue - } - go handleConnection(conn) - } -} diff --git a/src/client/client.go b/src/client/client.go new file mode 100644 index 0000000..a2ce8c7 --- /dev/null +++ b/src/client/client.go @@ -0,0 +1,292 @@ +package client + +import ( + "bufio" + "fmt" + "log" + "net" + "strings" + "strconv" + "ostrichdb-go/src/lib" + sdk "ostrichdb-go/src/sdk" + + tea "github.com/charmbracelet/bubbletea" +) + +const ( + STR = "STRING" + INT = "INTEGER" + INT_ARR = "[]INTEGER" + STR_ARR = "[]STRING" +) + +var currentUser User + +type Post struct { + id uint64 + Author *User + Content string + NumOfLikes uint64 + NumOfComments uint64 + WhoLikedPost []string + WhoCommented []string + Comments []Post +} + + +var postNames = []string {"author","content","numOfLikes","numOfComments","whoLikedPost","whoCommented"} + +type User struct { + Handle string + Following []string + Followers []string + //can add more here if needed +} + +func NewPostBuilder(user *User, content string) Post{ + return Post{ + Author: user, + Content: content, + NumOfLikes: 0, + NumOfComments: 0, + WhoLikedPost: nil, + WhoCommented: nil, + } +} + +func NewUserBuilder(name string) User { + return User{ + Handle: name, + Following: nil, + Followers: nil, + } +} + +// "FEED" +func HandleFeed(pageNum int) (string, error) { + conn, _ := net.Dial("tcp", "localhost:8080") + defer conn.Close() + fmt.Fprintf(conn, "FEED %v\n", pageNum) + return bufio.NewReader(conn).ReadString('\n') +} + +// "POST" +//Upon creation of a new post, create a new recordbuilder and the record itself and append into the "post" cluster +func HandlePost(proj lib.Project, col lib.Collection, p Post) error { + newPost := sdk.NewClusterBuilder(&proj, &col, create_post_name(&col)) + sdk.CreateCluster(newPost) + var record *lib.Record + for _ , postName:= range postNames{ + switch(postName){ + case "author": + record = sdk.NewRecordBuilder(&proj, &col, newPost, postName, STR, p.Author.Handle) + break + case "content": + record = sdk.NewRecordBuilder(&proj, &col, newPost, postName, STR, p.Content) + break + case "numOfLikes": + record = sdk.NewRecordBuilder(&proj, &col, newPost, postName, INT, "0") + break + case "numOfComments": + record = sdk.NewRecordBuilder(&proj, &col, newPost, postName, INT, "0") + break + case "whoLikedPost": + record = sdk.NewRecordBuilder(&proj, &col, newPost, postName, STR_ARR, fmt.Sprintf("%v", p.WhoLikedPost)) + break + case "whoCommented": + record = sdk.NewRecordBuilder(&proj, &col, newPost, postName, STR_ARR, fmt.Sprintf("%v", p.WhoCommented)) + } + + sdk.CreateRecord(record) + } + + return nil +} + +// "FETCH" +func HandleFetch(post string) (string, error) { + conn, _ := net.Dial("tcp", "localhost:8080") + defer conn.Close() + fmt.Fprintf(conn, "FETCH %v\n", post) + return bufio.NewReader(conn).ReadString('\n') +} + +// "COMMENT" +func HandleComment(post, content string) (string, error) { + conn, _ := net.Dial("tcp", "localhost:8080") + defer conn.Close() + fmt.Fprintf(conn, "COMMENT %v %v\n", post, content) + return bufio.NewReader(conn).ReadString('\n') +} + +// "LIKE" +func HandleLike(post string) (string, error) { + conn, _ := net.Dial("tcp", "localhost:8080") + defer conn.Close() + fmt.Fprintf(conn, "LIKE %v\n", post) + return bufio.NewReader(conn).ReadString('\n') +} + +type model struct { + cursor int + width int + height int + text string +} + +func (m model) Init() tea.Cmd { + return nil +} + +func initialModel() model { + return model{ + text: "", + } +} + +func (m model) View() string { + s := fmt.Sprintf("cursor %v\n", m.cursor) + s += fmt.Sprintf("1. cobbcoding\nThis is a post.\n\n") + s += fmt.Sprintf("2. stam\nThis is a post 2.\n\n") + for range m.height - 8 { + s += "\n" + } + s += fmt.Sprintf(":%v|", m.text) + return s +} + +func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + switch msg.(type) { + case tea.KeyMsg: + switch msg.(tea.KeyMsg).String() { + case "ctrl+c": + return m, tea.Quit + case "backspace": + if m.cursor > 0 { + m.cursor-- + m.text = m.text[:m.cursor] + } + break + case "enter": + m.text = "" + m.cursor = 0 + break + default: + m.text += msg.(tea.KeyMsg).String() + m.cursor += 1 + } + case tea.WindowSizeMsg: + m.width = msg.(tea.WindowSizeMsg).Width + m.height = msg.(tea.WindowSizeMsg).Height + break + } + return m, nil +} + +func Run() { + p := tea.NewProgram(initialModel(), tea.WithAltScreen()) + _, err := p.Run() + if err != nil { + log.Fatal("Could not start TUI") + } +} + + + +func parsePostId(id_s string) *Post { + ids := strings.Split(id_s, "-") + id, err := strconv.Atoi(ids[0]) + if err != nil { + fmt.Println("Could not convert to integer: ", ids[0]) + return nil + } + if id >= len(posts) { + fmt.Printf("Post %v does not exist\n", id) + return nil + } + cur_post := &posts[id] + for id_i := 1; id_i < len(ids); id_i += 1 { + id := ids[id_i] + id_val, err := strconv.Atoi(id) + if err != nil { + fmt.Println("Could not convert to integer: ", id) + return nil + } + if id_val >= len(cur_post.Comments) { + fmt.Printf("Post %v does not exist\n", id_val) + return nil + } + cur_post = &cur_post.Comments[id_val] + } + return cur_post +} + +var posts []Post + +func parseCommand(command string) (string, bool) { + currentUser:= NewUserBuilder("@Marshall") + words := strings.Fields(command) + var res string + if len(words) < 2 { + fmt.Println("Not a valid command") + return "", false + } + switch words[0] { + // example: POST + case "POST": + msg := strings.Join(words[1:], " ") + newPost := NewPostBuilder(¤tUser, msg) + newPost.id = uint64(len(posts)) + posts = append(posts, newPost) + res = fmt.Sprintf("%v", newPost) + + break + // example: FEED + case "FEED": + res = fmt.Sprintf(res, "%v", posts) + break + // example: FETCH + case "FETCH": + if len(words) < 2 { + fmt.Println("Not enough arguments to command ", words[0]) + return "", false + } + post := parsePostId(words[1]) + if post == nil { + fmt.Println("Could not parse ", words[1]) + return "", false + } + res = fmt.Sprintf(res, "%v", post) + break + // example: COMMENT + case "COMMENT": + if len(words) < 3 { + fmt.Println("Not enough arguments to command ", words[0]) + return "", false + } + msg := strings.Join(words[2:], " ") + post := parsePostId(words[1]) + if post == nil { + fmt.Println("Could not parse ", words[1]) + return "", false + } + fmt.Println(post) + comment := Post{id: uint64(len(post.Comments)), Content: msg} + post.Comments = append(post.Comments, comment) + res = "Comment posted successfully..." + break + // example: LIKE + case "LIKE": + post := parsePostId(words[1]) + if post == nil { + fmt.Println("Could not parse ", words[1]) + return "", false + } + post.NumOfLikes += 1 + res = "Post liked successfully..." + break + default: + log.Fatalf("Unknown command: %s\n", words[0]) + } + return res, true +} \ No newline at end of file diff --git a/src/client/helpers.go b/src/client/helpers.go new file mode 100644 index 0000000..9385a61 --- /dev/null +++ b/src/client/helpers.go @@ -0,0 +1,23 @@ +package client + +import ( + "fmt" + "ostrichdb-go/src/lib" + sdk "ostrichdb-go/src/sdk" +) + +// Helper functions for client will move later - Marshalla +func increment_post_count(collection *lib.Collection) int{ + currentCount:= sdk.GetClusterCount(collection) + incremented := currentCount + 1 + return incremented +} + + +// Only used to create a name for the post within OstrichDB e.g Post1, Post2, etc +func create_post_name(collection *lib.Collection) string{ + postCount:= increment_post_count(collection) + postName:= fmt.Sprintf("Post%d", postCount) + return postName +} + diff --git a/src/client/posts.go b/src/client/posts.go new file mode 100644 index 0000000..09f091a --- /dev/null +++ b/src/client/posts.go @@ -0,0 +1,30 @@ +package client + + +// type Post struct { +// id uint64 +// Author *User +// Content string +// NumOfLikes uint64 +// NumOfComments uint64 +// WhoLikedPost []string +// WhoCommented []string +// } + +// type User struct { +// Handle string +// Following []string +// Followers []string +// //can add more here if needed +// } + +// func NewPostBuilder(user *User, content string) Post{ +// return Post{ +// Author: user, +// Content: content, +// NumOfLikes: 0, +// NumOfComments: 0, +// WhoLikedPost: nil, +// WhoCommented: nil, +// } +// } diff --git a/src/library/types.go b/src/library/types.go new file mode 100644 index 0000000..4008a13 --- /dev/null +++ b/src/library/types.go @@ -0,0 +1 @@ +// package library \ No newline at end of file diff --git a/src/server/main.go b/src/server/main.go new file mode 100644 index 0000000..cef0a5c --- /dev/null +++ b/src/server/main.go @@ -0,0 +1,52 @@ +// package main + +// import ( +// "bufio" +// "fmt" +// "log" +// "net" +// "strconv" +// "strings" +// ) + +// const ( +// PORT = ":8080" +// ) + + + + + + +// func handleConnection(conn net.Conn) { +// defer conn.Close() +// msg, err := bufio.NewReader(conn).ReadString('\n') +// if err != nil { +// fmt.Println("Could not read message from connection: ", err) +// return +// } +// res, ok := parseCommand(msg) +// if !ok { +// conn.Write([]byte("Could not parse message...\n")) +// return +// } +// conn.Write([]byte(res)) +// } + + +// func main() { +// list, err := net.Listen("tcp", PORT) +// if err != nil { +// log.Fatalf("Could not start server: %s\n", err) +// } +// defer list.Close() +// fmt.Printf("Now accepting connections on port %v...\n", PORT) +// for { +// conn, err := list.Accept() +// if err != nil { +// fmt.Println("Could not accept incoming request: ", err) +// continue +// } +// go handleConnection(conn) +// } +// } From af04c4457980aa46da8b1f383cfc37b557617c61 Mon Sep 17 00:00:00 2001 From: SchoolyB Date: Sat, 15 Nov 2025 22:22:10 -0600 Subject: [PATCH 5/9] chore: update HandlePost function --- src/client/client.go | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/client/client.go b/src/client/client.go index a2ce8c7..21ebdcc 100644 --- a/src/client/client.go +++ b/src/client/client.go @@ -45,6 +45,7 @@ type User struct { func NewPostBuilder(user *User, content string) Post{ return Post{ + id: 0, Author: user, Content: content, NumOfLikes: 0, @@ -73,31 +74,36 @@ func HandleFeed(pageNum int) (string, error) { // "POST" //Upon creation of a new post, create a new recordbuilder and the record itself and append into the "post" cluster func HandlePost(proj lib.Project, col lib.Collection, p Post) error { - newPost := sdk.NewClusterBuilder(&proj, &col, create_post_name(&col)) - sdk.CreateCluster(newPost) + newPost := sdk.NewClusterBuilder(&col, create_post_name(&col)) + sdk.CreateCluster(newPost) //Each new Post by a user is its own Cluster within an OstrichDB Collection var record *lib.Record for _ , postName:= range postNames{ switch(postName){ case "author": - record = sdk.NewRecordBuilder(&proj, &col, newPost, postName, STR, p.Author.Handle) + record = sdk.NewRecordBuilder(newPost, postName, lib.RecordTypeStrings[lib.STRING], p.Author.Handle) break case "content": - record = sdk.NewRecordBuilder(&proj, &col, newPost, postName, STR, p.Content) + // fmt.Println("making a post with the following content: ", p.Content) + record = sdk.NewRecordBuilder(newPost, postName, lib.RecordTypeStrings[lib.STRING], p.Content) break case "numOfLikes": - record = sdk.NewRecordBuilder(&proj, &col, newPost, postName, INT, "0") + record = sdk.NewRecordBuilder(newPost, postName, lib.RecordTypeStrings[lib.INTEGER], "0") break case "numOfComments": - record = sdk.NewRecordBuilder(&proj, &col, newPost, postName, INT, "0") + record = sdk.NewRecordBuilder(newPost, postName, lib.RecordTypeStrings[lib.INTEGER], "0") break case "whoLikedPost": - record = sdk.NewRecordBuilder(&proj, &col, newPost, postName, STR_ARR, fmt.Sprintf("%v", p.WhoLikedPost)) + record = sdk.NewRecordBuilder(newPost, postName, lib.RecordTypeStrings[lib.STRING_ARRAY], fmt.Sprintf("%v", p.WhoLikedPost)) break case "whoCommented": - record = sdk.NewRecordBuilder(&proj, &col, newPost, postName, STR_ARR, fmt.Sprintf("%v", p.WhoCommented)) + record = sdk.NewRecordBuilder(newPost, postName, lib.RecordTypeStrings[lib.STRING_ARRAY], fmt.Sprintf("%v", p.WhoCommented)) } - sdk.CreateRecord(record) + + err:= sdk.CreateRecord(record) + if err != nil { + return err + } } return nil From 43d252e54395838fb53660863f2d10f46aed72d9 Mon Sep 17 00:00:00 2001 From: SchoolyB Date: Sun, 16 Nov 2025 19:52:40 -0600 Subject: [PATCH 6/9] chore: add new helper functions/minor changes --- src/client/client.go | 88 +++++++++++++++++++++++++++++++++++-------- src/client/helpers.go | 87 +++++++++++++++++++++++++++++++++++++++++- src/server/main.go | 3 +- 3 files changed, 161 insertions(+), 17 deletions(-) diff --git a/src/client/client.go b/src/client/client.go index 21ebdcc..05932af 100644 --- a/src/client/client.go +++ b/src/client/client.go @@ -33,6 +33,68 @@ type Post struct { Comments []Post } +// OstrichDB cluster response structure +type ClusterResponse struct { + ClusterName string `json:"cluster_name"` + ClusterID int `json:"cluster_id"` + RecordCount int `json:"record_count"` + Records []RecordField `json:"records"` +} + +type RecordField struct { + Name string `json:"name"` + Type string `json:"type"` + Value interface{} `json:"value"` +} + +// Helper method to convert ClusterResponse to Post +func (cr *ClusterResponse) ToPost() (*Post, error) { + post := &Post{ + id: uint64(cr.ClusterID), + } + + // Parse records into Post fields + for _, record := range cr.Records { + switch record.Name { + case "author": + if authorStr, ok := record.Value.(string); ok { + post.Author = &User{Handle: authorStr} + } + case "content": + if content, ok := record.Value.(string); ok { + post.Content = content + } + case "numOfLikes": + if likes, ok := record.Value.(uint64); ok { + post.NumOfLikes = uint64(likes) + } + case "numOfComments": + if comments, ok := record.Value.(uint64); ok { + post.NumOfComments = uint64(comments) + } + case "whoLikedPost": + if arr, ok := record.Value.([]interface{}); ok { + post.WhoLikedPost = make([]string, len(arr)) + for i, v := range arr { + if str, ok := v.(string); ok { + post.WhoLikedPost[i] = str + } + } + } + case "whoCommented": + if arr, ok := record.Value.([]interface{}); ok { + post.WhoCommented = make([]string, len(arr)) + for i, v := range arr { + if str, ok := v.(string); ok { + post.WhoCommented[i] = str + } + } + } + } + } + + return post, nil +} var postNames = []string {"author","content","numOfLikes","numOfComments","whoLikedPost","whoCommented"} @@ -40,6 +102,7 @@ type User struct { Handle string Following []string Followers []string + Posts []Post //can add more here if needed } @@ -71,10 +134,9 @@ func HandleFeed(pageNum int) (string, error) { return bufio.NewReader(conn).ReadString('\n') } -// "POST" -//Upon creation of a new post, create a new recordbuilder and the record itself and append into the "post" cluster -func HandlePost(proj lib.Project, col lib.Collection, p Post) error { - newPost := sdk.NewClusterBuilder(&col, create_post_name(&col)) +//Creates a new Post (p) in a Collection (c). Upon creation each Post is stored as a Cluster within an OstrichDB Collection +func HandlePost(c lib.Collection, p Post) error { + newPost := sdk.NewClusterBuilder(&c, create_post_name(&c)) sdk.CreateCluster(newPost) //Each new Post by a user is its own Cluster within an OstrichDB Collection var record *lib.Record for _ , postName:= range postNames{ @@ -99,7 +161,6 @@ func HandlePost(proj lib.Project, col lib.Collection, p Post) error { record = sdk.NewRecordBuilder(newPost, postName, lib.RecordTypeStrings[lib.STRING_ARRAY], fmt.Sprintf("%v", p.WhoCommented)) } - err:= sdk.CreateRecord(record) if err != nil { return err @@ -109,13 +170,12 @@ func HandlePost(proj lib.Project, col lib.Collection, p Post) error { return nil } -// "FETCH" -func HandleFetch(post string) (string, error) { - conn, _ := net.Dial("tcp", "localhost:8080") - defer conn.Close() - fmt.Fprintf(conn, "FETCH %v\n", post) - return bufio.NewReader(conn).ReadString('\n') -} +//Fetches a specific Post (p) from a Collection (c) +// The Collection is based on the Author (a) that created the Post +// func HandleFetch(p Post, c *lib.Collection,a *User) (string, error) { +// // post:= + +// } // "COMMENT" func HandleComment(post, content string) (string, error) { @@ -197,8 +257,6 @@ func Run() { } } - - func parsePostId(id_s string) *Post { ids := strings.Split(id_s, "-") id, err := strconv.Atoi(ids[0]) @@ -246,6 +304,7 @@ func parseCommand(command string) (string, bool) { posts = append(posts, newPost) res = fmt.Sprintf("%v", newPost) + break // example: FEED case "FEED": @@ -276,7 +335,6 @@ func parseCommand(command string) (string, bool) { fmt.Println("Could not parse ", words[1]) return "", false } - fmt.Println(post) comment := Post{id: uint64(len(post.Comments)), Content: msg} post.Comments = append(post.Comments, comment) res = "Comment posted successfully..." diff --git a/src/client/helpers.go b/src/client/helpers.go index 9385a61..ffe9384 100644 --- a/src/client/helpers.go +++ b/src/client/helpers.go @@ -1,7 +1,10 @@ package client import ( + "encoding/json" "fmt" + "io" + "net/http" "ostrichdb-go/src/lib" sdk "ostrichdb-go/src/sdk" ) @@ -13,7 +16,6 @@ func increment_post_count(collection *lib.Collection) int{ return incremented } - // Only used to create a name for the post within OstrichDB e.g Post1, Post2, etc func create_post_name(collection *lib.Collection) string{ postCount:= increment_post_count(collection) @@ -21,3 +23,86 @@ func create_post_name(collection *lib.Collection) string{ return postName } +//Used to fetch an entire Post (p) which is stored as a single cluster within OstrichDB +// Even though this function claims to fetch a post by id. its really looking for the post's name +// THis is the case becauser the ID is infact inside the name +func FetchPostByID(c *lib.Cluster, id uint64) Post{ + var post Post + client:= c.Collection.Project.Client + projName:= c.Collection.Project.Name + colName:= c.Collection.Name + cluName:= fmt.Sprintf("Post%d", id) + + path:= fmt.Sprintf("%s/projects/%s/collections/%s/clusters/%s", lib.OSTRICHDB_ADDRESS, projName, colName, cluName ) + + response, err:= lib.Get(client, path) + if err != nil { + return post + } + + defer response.Body.Close() + + if response.StatusCode != http.StatusOK { + return post + } + + // Read response body + body, err := io.ReadAll(response.Body) + if err != nil { + return post + } + + // Unmarshal the cluster JSON response + var clusterResp ClusterResponse + err = json.Unmarshal(body, &clusterResp) + if err != nil { + return post + } + + // Convert ClusterResponse to Post + fetchedPost, err := clusterResp.ToPost() + if err != nil { + return post + } + + return *fetchedPost +} + +// Fetch the number of likes for a specific post +func FetchNumOfLikes(c *lib.Cluster, id uint64) uint64 { + post := FetchPostByID(c,id) + return post.NumOfLikes +} + +// Fetch the number of comments for a specific post +func FetchNumOfComments(c *lib.Cluster, id uint64) uint64 { + post := FetchPostByID(c,id) + return post.NumOfComments +} + +// Fetch the list of users who liked a specific post +func FetchPostLikesList(c *lib.Cluster, id uint64) []string { + post := FetchPostByID(c,id) + return post.WhoLikedPost +} + +// Fetch the list of users who commented on a specific post +func FetchPostCommentersList(c *lib.Cluster, id uint64) []string { + post := FetchPostByID(c,id) + return post.WhoCommented +} + +// Fetch the author of a specific post +func FetchPostAuthor(c *lib.Cluster, id uint64) string { + post := FetchPostByID(c,id) + if post.Author != nil { + return post.Author.Handle + } + return "Unknown Author" +} + +// Fetch the actual comments (Post objects) for a specific post +func FetchPostCommnets(c *lib.Cluster, id uint64) []Post { + post := FetchPostByID(c,id) + return post.Comments +} \ No newline at end of file diff --git a/src/server/main.go b/src/server/main.go index cef0a5c..556b8e7 100644 --- a/src/server/main.go +++ b/src/server/main.go @@ -1,3 +1,4 @@ + // package main // import ( @@ -49,4 +50,4 @@ // } // go handleConnection(conn) // } -// } +// } \ No newline at end of file From 5b23123b746e31a5020c1b1011cc5571dc724619 Mon Sep 17 00:00:00 2001 From: SchoolyB Date: Sun, 16 Nov 2025 19:52:49 -0600 Subject: [PATCH 7/9] chore: update main --- main/main.go | 45 ++++++++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/main/main.go b/main/main.go index a8eb4b2..7b17b3a 100644 --- a/main/main.go +++ b/main/main.go @@ -1,38 +1,57 @@ package main import ( - c "client" //uncomment when ready to use client functions - // "fmt" + "fmt" "ostrichdb-go/src/lib" + c "client" //uncomment when ready to use client functions sdk "ostrichdb-go/src/sdk" ) + var config lib.Config = *sdk.NewConfigBuilder() var client lib.Client = *sdk.NewClientBuilder(&config) var project lib.Project = *sdk.NewProjectBuilder(&client, "twix") func main (){ + var err error - // projectErr:= sdk.CreateProject(&project) - // if projectErr != nil { - // fmt.Println("Error creating project") - // fmt.Println(projectErr) - // } + // START | START | START | START | START | START | START | START | START + // The following code is an example of the flow for creating a + // Project(Dir of Users), Specific User Collection, and a first Post(Cluster) + // Once 'END' is reached an exmaple of another flow begins - //Note: Whenever implementing user auth on client please replace "Marshall" with username input + err= sdk.CreateProject(&project) + if err != nil { + fmt.Println("Error creating project") + fmt.Println("Error: ",err) + } + + // //Note: Whenever implementing user auth on client please replace "Marshall" with username input collection:= sdk.NewCollectionBuilder(&project, "Marshall") - // collectionErr:= sdk.CreateCollection(collection) + err = sdk.CreateCollection(collection) - // if collectionErr != nil { - // fmt.Println("Error creating collection") - // } + if err != nil { + fmt.Println("Error creating Collection") + fmt.Println("Error: ",err) + } //Testing things out currentUser:= c.NewUserBuilder("@Marshall") + //TODO: If there is a space in the string value of Content is not stored. OstrichDB engine issue newPost:= c.NewPostBuilder(¤tUser, "Hello World") - c.HandlePost(project, *collection, newPost) + + err = c.HandlePost(*collection, newPost) + if err != nil { + fmt.Println("Error appending new post to a Collection") + fmt.Println("Error: ",err) + } + // END | END| END| END| END| END| END| END| END| END + + // Fetching a Post from OstrichDB + specificPost:= sdk.NewClusterBuilder(collection, "Marshall") + fmt.Println(c.FetchPostAuthor(specificPost, 1)) // c.Run() } From 6f0c1c01680cb48760b92880027b3c21b6fc4d86 Mon Sep 17 00:00:00 2001 From: SchoolyB Date: Fri, 21 Nov 2025 17:17:59 -0600 Subject: [PATCH 8/9] bump --- ostrichdb-go | 2 +- src/client/client.go | 62 ++++++++++++++++++++++++++++---------------- 2 files changed, 40 insertions(+), 24 deletions(-) diff --git a/ostrichdb-go b/ostrichdb-go index 382ced8..6cdacee 160000 --- a/ostrichdb-go +++ b/ostrichdb-go @@ -1 +1 @@ -Subproject commit 382ced89c16d87959a7b9b057d8c30b66c136816 +Subproject commit 6cdacee989b60448fdc5d0492e1bb7b3465cd4cd diff --git a/src/client/client.go b/src/client/client.go index 05932af..3c9f618 100644 --- a/src/client/client.go +++ b/src/client/client.go @@ -30,7 +30,7 @@ type Post struct { NumOfComments uint64 WhoLikedPost []string WhoCommented []string - Comments []Post + Comments []string } // OstrichDB cluster response structure @@ -90,13 +90,22 @@ func (cr *ClusterResponse) ToPost() (*Post, error) { } } } + case "comments": + if arr, ok := record.Value.([]interface{}); ok{ + post.Comments = make([]string, len(arr)) + for i, v:= range arr { + if str, ok:= v.(string); ok{ + post.Comments[i] = str + } + } + } } } return post, nil } -var postNames = []string {"author","content","numOfLikes","numOfComments","whoLikedPost","whoCommented"} +var postRecordNames = []string {"author","content","numOfLikes","numOfComments","whoLikedPost","whoCommented", "comments"} type User struct { Handle string @@ -115,6 +124,7 @@ func NewPostBuilder(user *User, content string) Post{ NumOfComments: 0, WhoLikedPost: nil, WhoCommented: nil, + } } @@ -134,31 +144,31 @@ func HandleFeed(pageNum int) (string, error) { return bufio.NewReader(conn).ReadString('\n') } -//Creates a new Post (p) in a Collection (c). Upon creation each Post is stored as a Cluster within an OstrichDB Collection +//Creates a new Post (p) in a Collection (c) +//Upon creation each Post is stored as a Cluster within an OstrichDB Collection func HandlePost(c lib.Collection, p Post) error { newPost := sdk.NewClusterBuilder(&c, create_post_name(&c)) - sdk.CreateCluster(newPost) //Each new Post by a user is its own Cluster within an OstrichDB Collection + sdk.CreateCluster(newPost) var record *lib.Record - for _ , postName:= range postNames{ + for _ , postName:= range postRecordNames{ switch(postName){ case "author": - record = sdk.NewRecordBuilder(newPost, postName, lib.RecordTypeStrings[lib.STRING], p.Author.Handle) + record = sdk.NewRecordBuilder(newPost, postName, lib.STRING, p.Author.Handle) break case "content": - // fmt.Println("making a post with the following content: ", p.Content) - record = sdk.NewRecordBuilder(newPost, postName, lib.RecordTypeStrings[lib.STRING], p.Content) + record = sdk.NewRecordBuilder(newPost, postName, lib.STRING, p.Content) break case "numOfLikes": - record = sdk.NewRecordBuilder(newPost, postName, lib.RecordTypeStrings[lib.INTEGER], "0") + record = sdk.NewRecordBuilder(newPost, postName, lib.INTEGER, "0") break case "numOfComments": - record = sdk.NewRecordBuilder(newPost, postName, lib.RecordTypeStrings[lib.INTEGER], "0") + record = sdk.NewRecordBuilder(newPost, postName, lib.INTEGER, "0") break case "whoLikedPost": - record = sdk.NewRecordBuilder(newPost, postName, lib.RecordTypeStrings[lib.STRING_ARRAY], fmt.Sprintf("%v", p.WhoLikedPost)) + record = sdk.NewRecordBuilder(newPost, postName, lib.STRING_ARRAY, fmt.Sprintf("%v", p.WhoLikedPost)) break case "whoCommented": - record = sdk.NewRecordBuilder(newPost, postName, lib.RecordTypeStrings[lib.STRING_ARRAY], fmt.Sprintf("%v", p.WhoCommented)) + record = sdk.NewRecordBuilder(newPost, postName, lib.STRING_ARRAY, fmt.Sprintf("%v", p.WhoCommented)) } err:= sdk.CreateRecord(record) @@ -170,24 +180,30 @@ func HandlePost(c lib.Collection, p Post) error { return nil } -//Fetches a specific Post (p) from a Collection (c) +// Fetches a specific Post (p) from a Collection (c) // The Collection is based on the Author (a) that created the Post -// func HandleFetch(p Post, c *lib.Collection,a *User) (string, error) { -// // post:= +// func HandleFetch(p Post, c *lib.Collection,) (string, error) { +// path:= +// post:= lib.Get() // } // "COMMENT" -func HandleComment(post, content string) (string, error) { - conn, _ := net.Dial("tcp", "localhost:8080") - defer conn.Close() - fmt.Fprintf(conn, "COMMENT %v %v\n", post, content) - return bufio.NewReader(conn).ReadString('\n') -} +// TODO: before working on commenets. Have to update OstrichDB src code +// and ensuring there is a way to append a new value to a record that is an array +// func HandleComment(post Post, comment string) (string, error) { +// conn, _ := net.Dial("tcp", "localhost:8080") +// defer conn.Close() +// fmt.Fprintf(conn, "COMMENT %v %v\n", post, content) +// return bufio.NewReader(conn).ReadString('\n') +// } // "LIKE" -func HandleLike(post string) (string, error) { - conn, _ := net.Dial("tcp", "localhost:8080") +func HandleLike(col lib.Collection,clu lib.Cluster, post Post) (string, error) { + + record := sdk.NewRecordBuilder(&clu, "numOfLikes", lib.INTEGER) + + sdk.UpdateRecordValue() defer conn.Close() fmt.Fprintf(conn, "LIKE %v\n", post) return bufio.NewReader(conn).ReadString('\n') From 82832474d603de5dd0ccf8dc78ec103bd9dbb798 Mon Sep 17 00:00:00 2001 From: SchoolyB Date: Sun, 23 Nov 2025 20:24:09 -0600 Subject: [PATCH 9/9] fix errors/update gitignore --- .gitignore | 3 --- main/go.mod | 33 ++++++++++++++++++++++++++++++++ main/go.sum | 43 ++++++++++++++++++++++++++++++++++++++++++ src/client/client.go | 15 ++++++--------- src/client/go.mod | 31 ++++++++++++++++++++++++++++++ src/client/go.sum | 45 ++++++++++++++++++++++++++++++++++++++++++++ src/library/go.mod | 3 +++ src/server/go.mod | 5 +++++ 8 files changed, 166 insertions(+), 12 deletions(-) create mode 100644 main/go.mod create mode 100644 main/go.sum create mode 100644 src/client/go.mod create mode 100644 src/client/go.sum create mode 100644 src/library/go.mod create mode 100644 src/server/go.mod diff --git a/.gitignore b/.gitignore index 56a03de..43c4ed3 100644 --- a/.gitignore +++ b/.gitignore @@ -28,9 +28,6 @@ bin/system/ # Allow specific Go and Odin source files !main/main.odin -# Exclude Go module files if not needed -go.sum -go.mod # System and IDE files .DS_Store diff --git a/main/go.mod b/main/go.mod new file mode 100644 index 0000000..730a203 --- /dev/null +++ b/main/go.mod @@ -0,0 +1,33 @@ +module twix-main + +go 1.25.3 + +require ostrichdb-go v0.0.0 + +require ( + client v0.0.0-00010101000000-000000000000 // indirect + github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect + github.com/charmbracelet/bubbletea v1.3.10 // indirect + github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect + github.com/charmbracelet/lipgloss v1.1.0 // indirect + github.com/charmbracelet/x/ansi v0.10.1 // indirect + github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect + github.com/charmbracelet/x/term v0.2.1 // indirect + github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect + github.com/joho/godotenv v1.5.1 // indirect + github.com/lucasb-eyer/go-colorful v1.2.0 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-localereader v0.0.1 // indirect + github.com/mattn/go-runewidth v0.0.16 // indirect + github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect + github.com/muesli/cancelreader v0.2.2 // indirect + github.com/muesli/termenv v0.16.0 // indirect + github.com/rivo/uniseg v0.4.7 // indirect + github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect + golang.org/x/sys v0.36.0 // indirect + golang.org/x/text v0.3.8 // indirect +) + +replace client => ../src/client + +replace ostrichdb-go => ../ostrichdb-go diff --git a/main/go.sum b/main/go.sum new file mode 100644 index 0000000..116af2d --- /dev/null +++ b/main/go.sum @@ -0,0 +1,43 @@ +github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= +github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= +github.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlvF9nRvCICw= +github.com/charmbracelet/bubbletea v1.3.10/go.mod h1:ORQfo0fk8U+po9VaNvnV95UPWA1BitP1E0N6xJPlHr4= +github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs= +github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk= +github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY= +github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30= +github.com/charmbracelet/x/ansi v0.10.1 h1:rL3Koar5XvX0pHGfovN03f5cxLbCF2YvLeyz7D2jVDQ= +github.com/charmbracelet/x/ansi v0.10.1/go.mod h1:3RQDQ6lDnROptfpWuUVIUG64bD2g2BgntdxH0Ya5TeE= +github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd h1:vy0GVL4jeHEwG5YOXDmi86oYw2yuYUGqz6a8sLwg0X8= +github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs= +github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ= +github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg= +github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4= +github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= +github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= +github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88= +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI= +github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo= +github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= +github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= +github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc= +github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= +github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= diff --git a/src/client/client.go b/src/client/client.go index 3c9f618..fb49a46 100644 --- a/src/client/client.go +++ b/src/client/client.go @@ -30,7 +30,7 @@ type Post struct { NumOfComments uint64 WhoLikedPost []string WhoCommented []string - Comments []string + Comments []Post } // OstrichDB cluster response structure @@ -92,10 +92,10 @@ func (cr *ClusterResponse) ToPost() (*Post, error) { } case "comments": if arr, ok := record.Value.([]interface{}); ok{ - post.Comments = make([]string, len(arr)) + post.Comments = make([]Post, len(arr)) for i, v:= range arr { - if str, ok:= v.(string); ok{ - post.Comments[i] = str + if p, ok:= v.(Post); ok{ + post.Comments[i] = p } } } @@ -199,11 +199,8 @@ func HandlePost(c lib.Collection, p Post) error { // } // "LIKE" -func HandleLike(col lib.Collection,clu lib.Cluster, post Post) (string, error) { - - record := sdk.NewRecordBuilder(&clu, "numOfLikes", lib.INTEGER) - - sdk.UpdateRecordValue() +func HandleLike(post string) (string, error) { + conn, _ := net.Dial("tcp", "localhost:8080") defer conn.Close() fmt.Fprintf(conn, "LIKE %v\n", post) return bufio.NewReader(conn).ReadString('\n') diff --git a/src/client/go.mod b/src/client/go.mod new file mode 100644 index 0000000..496c7aa --- /dev/null +++ b/src/client/go.mod @@ -0,0 +1,31 @@ +module client + +go 1.25.3 + +require github.com/charmbracelet/bubbletea v1.3.10 + +require ostrichdb-go v0.0.0 + +require ( + github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect + github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect + github.com/charmbracelet/lipgloss v1.1.0 // indirect + github.com/charmbracelet/x/ansi v0.10.1 // indirect + github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect + github.com/charmbracelet/x/term v0.2.1 // indirect + github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect + github.com/joho/godotenv v1.5.1 // indirect + github.com/lucasb-eyer/go-colorful v1.2.0 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-localereader v0.0.1 // indirect + github.com/mattn/go-runewidth v0.0.16 // indirect + github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect + github.com/muesli/cancelreader v0.2.2 // indirect + github.com/muesli/termenv v0.16.0 // indirect + github.com/rivo/uniseg v0.4.7 // indirect + github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect + golang.org/x/sys v0.36.0 // indirect + golang.org/x/text v0.3.8 // indirect +) + +replace ostrichdb-go => ../../ostrichdb-go diff --git a/src/client/go.sum b/src/client/go.sum new file mode 100644 index 0000000..6bfe030 --- /dev/null +++ b/src/client/go.sum @@ -0,0 +1,45 @@ +github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= +github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= +github.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlvF9nRvCICw= +github.com/charmbracelet/bubbletea v1.3.10/go.mod h1:ORQfo0fk8U+po9VaNvnV95UPWA1BitP1E0N6xJPlHr4= +github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs= +github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk= +github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY= +github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30= +github.com/charmbracelet/x/ansi v0.10.1 h1:rL3Koar5XvX0pHGfovN03f5cxLbCF2YvLeyz7D2jVDQ= +github.com/charmbracelet/x/ansi v0.10.1/go.mod h1:3RQDQ6lDnROptfpWuUVIUG64bD2g2BgntdxH0Ya5TeE= +github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd h1:vy0GVL4jeHEwG5YOXDmi86oYw2yuYUGqz6a8sLwg0X8= +github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs= +github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ= +github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg= +github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4= +github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= +github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= +github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88= +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI= +github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo= +github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= +github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= +github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc= +github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= +github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= +golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E= +golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= diff --git a/src/library/go.mod b/src/library/go.mod new file mode 100644 index 0000000..28c16b9 --- /dev/null +++ b/src/library/go.mod @@ -0,0 +1,3 @@ +module library.com + +go 1.23.1 diff --git a/src/server/go.mod b/src/server/go.mod new file mode 100644 index 0000000..805d151 --- /dev/null +++ b/src/server/go.mod @@ -0,0 +1,5 @@ +module twix + +go 1.25.3 + +replace lib => ../library