DEV Community

Shrijith Venkatramana
Shrijith Venkatramana

Posted on

3 2 2 3 3

Getting DBChat Working For the First Time In VSCode - Part 9

Hi there! I'm Shrijith Venkatrama, the founder of Hexmos. Right now, I’m building LiveAPI, a super-convenient tool that simplifies engineering workflows by generating awesome API docs from your code in minutes.

In this tutorial series, I am on a journey to build for myself DBChat - a simple tool for using AI chat to explore and evolve databases.

See previous posts to get more context:

  1. Building DBChat - Explore and Evolve Your DB with Simple Chat (Part 1)
  2. DBChat: Getting a Toy REPL Going in Golang (Part 2)
  3. DBChat Part 3 - Configure , Connect & Dump Databases
  4. Chat With Your DB via DBChat & Gemini (Part 4)
  5. The Language Server Protocol - Building DBChat (Part 5)
  6. Making DBChat VSCode Extension - Ping Pong With LSP Backend (Part 6)
  7. Starting a VSCode Extension UI For DBChat (Part 7)
  8. Manage TOML Configuration From VSCode Extension - DBChat Part 8

Some screenshots of the working version

The default view for DBChat will look like this:

Default View

After selecting a database - we get a chat view:

Chat View

Now, we will try to get "gmail users" vs "non-gmail users" with the simplest of prompts/requests:

Gmail users

The query is perfect. When I do exec 1 I get exactly the result expected in a table format.

Similar logic works for "get all non-gmail users" query as well.

A More Detailed View Into the DBChat Updates

This code handles communication with an LSP client, likely a language server protocol client in a code editor. Here's a breakdown:

1. Setting the Stage: Configuration and Initialization

  • Loading the Config: The code starts by reading the configuration file. This file probably holds settings like database connection strings.
  • Creating the Query Handler: It then sets up the queryHandler, which is likely responsible for understanding and executing user requests.
  • Building the Handler: Finally, it creates the DBChatHandler, a core component that manages the configuration, query handler, and potentially the database connection.
config, err := utils.LoadConfig()
if err != nil {
    log.Printf("Warning: Could not load config: %v", err)
    config = &utils.Config{Connections: make(map[string]string)}
}

queryHandler, err := query.NewHandler(config.LLM.GeminiKey)
if err != nil {
    log.Printf("Warning: Could not create query handler: %v", err)
}

handler := &DBChatHandler{
    config:       config,
    queryHandler: queryHandler,
}
Enter fullscreen mode Exit fullscreen mode

2. LSP Communication: The Heartbeat

  • The LSP Loop: The program enters a continuous loop, constantly listening for messages from the LSP client.
  • Reading Messages: It carefully reads messages from the client, paying close attention to the Content-Length header to know how much data to expect.
  • Parsing Messages: Once received, the raw data is transformed into a structured JSON-RPC message, making it easier to understand.
for {
    // Read Content-Length header 
    // ... (code for reading header) ...

    // Read message body 
    // ... (code for reading message body) ...

    // Parse JSON-RPC message
    var msg JSONRPCMessage
    if err := json.Unmarshal(body, &msg); err != nil { 
        // ... (handle parsing error) ...
    }
}
Enter fullscreen mode Exit fullscreen mode

3. Handling Requests: What to Do?

  • "ping" Requests: Simple! The program responds with a "pong" to acknowledge the client's ping.
  • "chat" Requests: This is where the action happens.
    • The code extracts the user's chat message.
    • It hands off this message to the Eval method within the DBChatHandler. This method likely interacts with the database and the queryHandler to process the request.
    • The result of the processing is then packaged into a response and sent back to the client.
switch msg.Method {
    case "ping":
        response.Result = "pong"
    case "chat":
        var params struct {
            Message string `json:"message"`
        }
        if err := json.Unmarshal(msg.Params, &params); err != nil {
            // ... (handle invalid params) ...
        }

        log.Printf("Processing chat message: %q", params.Message)
        result := handler.Eval(params.Message) 
        log.Printf("Eval result: %q", result) 

        response.Result = map[string]interface{}{
            "message": result,
        }
    // ... (handle other methods) ...
}
Enter fullscreen mode Exit fullscreen mode

4. Error Handling and Responses

  • Catching Errors: If anything goes wrong – like problems parsing the message or issues with the database – the program gracefully handles the error and sends an appropriate error message back to the client.
  • Sending Responses: Finally, the program crafts the response message in the correct JSON-RPC format and sends it back to the client.
if err := writeResponse(response); err != nil {
    log.Printf("Error writing response: %v", err)
}
Enter fullscreen mode Exit fullscreen mode

Conclusion

DBchat now is able to manage database connections, focus on any database, allow making queries in natural languages and finally get good responses in table format based on database contents.

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

Top comments (0)

Cloudinary image

Video API: manage, encode, and optimize for any device, channel or network condition. Deliver branded video experiences in minutes and get deep engagement insights.

Learn more

👋 Kindness is contagious

Engage with a sea of insights in this enlightening article, highly esteemed within the encouraging DEV Community. Programmers of every skill level are invited to participate and enrich our shared knowledge.

A simple "thank you" can uplift someone's spirits. Express your appreciation in the comments section!

On DEV, sharing knowledge smooths our journey and strengthens our community bonds. Found this useful? A brief thank you to the author can mean a lot.

Okay