diff --git a/README.md b/README.md index 7c8ff79..c74e92a 100644 --- a/README.md +++ b/README.md @@ -1,109 +1,189 @@ -# Notificationcenter pub/sub library +# Notificationcenter Pub/Sub Library [![Build Status](https://github.com/geniusrabbit/notificationcenter/workflows/Tests/badge.svg)](https://github.com/geniusrabbit/notificationcenter/actions?workflow=Tests) [![Go Report Card](https://goreportcard.com/badge/github.com/geniusrabbit/notificationcenter)](https://goreportcard.com/report/github.com/geniusrabbit/notificationcenter) [![GoDoc](https://godoc.org/github.com/geniusrabbit/notificationcenter?status.svg)](https://godoc.org/github.com/geniusrabbit/notificationcenter) [![Coverage Status](https://coveralls.io/repos/github/geniusrabbit/notificationcenter/badge.svg)](https://coveralls.io/github/geniusrabbit/notificationcenter) -> License Apache 2.0 +> License: Apache 2.0 -Publish/subscribe messaging, often referred to as pub/sub messaging, serves as a pivotal form of asynchronous communication between services within serverless and microservices architectures. Operating on a pub/sub model, this approach entails the instantaneous transmission of any published message to all subscribers associated with the corresponding topic. The utility of pub/sub messaging extends to enabling event-driven architectures and the seamless decoupling of applications, ultimately yielding improvements in performance, reliability, and scalability. +The **NotificationCenter** library provides a unified interface for publish/subscribe (pub/sub) messaging in Go applications. It simplifies asynchronous communication between services in serverless and microservices architectures by abstracting the complexities of various message brokers. -At its core, this mechanism involves the interaction between publishers, who disseminate messages, and subscribers, who receive and act upon these messages. By employing this model, systems can leverage the power of loosely coupled communication, enhancing the adaptability of individual components within the broader infrastructure. +With NotificationCenter, you can seamlessly integrate different pub/sub backends like Kafka, NATS, Redis, PostgreSQL, and more without altering your application logic. This promotes decoupled architectures, enhancing performance, reliability, and scalability. -To streamline the implementation of this messaging paradigm, libraries provide essential foundational elements that facilitate the utilization of various queue implementations. These libraries abstract the complexities of interacting with diverse queuing systems, thereby simplifying the development of pub/sub services. This not only promotes efficient communication between services but also empowers developers to concentrate on the business logic and functionality of their applications without becoming entangled in the intricacies of messaging infrastructures. +## Table of Contents -- [Using examples](#using-examples) - - [Create new publisher processor](#create-new-publisher-processor) - - [Send event by the notification publisher](#send-event-by-the-notification-publisher) - - [Subscribe by the specific notification publisher](#subscribe-by-the-specific-notification-publisher) -- Modules - - [Kafka](kafka) - - [NATS](nats) - - [NATS Stream](natstream) - - [PostgreSQL](pg) - - [Redis](redis) - - [Golang Chanels implementation](gochan) - - [Golang time interval executor](interval) +- [Features](#features) +- [Supported Modules](#supported-modules) +- [Installation](#installation) +- [Usage Examples](#usage-examples) + - [Import the Package](#import-the-package) + - [Create a Publisher](#create-a-publisher) + - [Publish Messages](#publish-messages) + - [Subscribe to Messages](#subscribe-to-messages) - [TODO](#todo) +- [License](#license) -## Using examples +## Features -Basic examples of usage. +- **Unified Interface**: Interact with multiple pub/sub backends using a consistent API. +- **Easy Integration**: Quickly set up publishers and subscribers with minimal configuration. +- **Backend Flexibility**: Swap out message brokers without changing your application code. +- **Event-Driven Architecture**: Facilitate loosely coupled communication between services. +- **Scalability**: Improve performance and reliability by decoupling application components. + +## Supported Modules + +- [Kafka](kafka) +- [NATS](nats) +- [NATS Streaming](natsstream) +- [PostgreSQL](pg) +- [Redis](redis) +- [Go Channels](gochan) +- [Time Interval Executor](interval) + +## Installation + +Install the library using `go get`: + +```bash +go get github.com/geniusrabbit/notificationcenter/v2 +``` + +## Usage Examples + +Below are basic examples demonstrating how to use NotificationCenter in your Go application. + +### Import the Package ```go -import( +import ( nc "github.com/geniusrabbit/notificationcenter/v2" ) ``` -### Create new publisher processor +### Create a Publisher + +Create a new publisher using one of the supported backends. For example, using **NATS**: ```go -// Create new publisher processor -eventStream, err = nats.NewPublisher(nats.WithNatsURL("nats://hostname:4222/group?topics=event")) +import ( + "github.com/geniusrabbit/notificationcenter/v2/nats" + "log" +) + +// Create a new NATS publisher +eventStream, err := nats.NewPublisher( + nats.WithNatsURL("nats://hostname:4222"), +) if err != nil { log.Fatal(err) } -// Register stream processor +// Register the publisher with NotificationCenter err = nc.Register("events", eventStream) if err != nil { log.Fatal(err) } ``` -### Send event by the notification publisher +### Publish Messages + +You can publish messages using global functions or by obtaining a publisher interface. + +**Using Global Functions:** ```go -// Send by global functions -nc.Publish(context.Background(), "events", message{title: "event 1"}) +import ( + "context" +) + +// Define your message structure +type Message struct { + Title string +} -// Send by logger interface -events := nc.Publisher("events") -events.Publish(context.Background(), message{title: "event 2"}) +// Publish a message globally +nc.Publish(context.Background(), "events", Message{Title: "Event 1"}) ``` -### Subscribe by the specific notification publisher +**Using Publisher Interface:** + +```go +// Get the publisher interface +eventsPublisher := nc.Publisher("events") + +// Publish a message +eventsPublisher.Publish(context.Background(), Message{Title: "Event 2"}) +``` + +### Subscribe to Messages + +Create a subscriber and register it with NotificationCenter. ```go import ( - nc "github.com/geniusrabbit/notificationcenter/v2" + "context" + "fmt" + "github.com/geniusrabbit/notificationcenter/v2" "github.com/geniusrabbit/notificationcenter/v2/nats" + "github.com/geniusrabbit/notificationcenter/v2/interval" + "time" ) func main() { ctx := context.Background() - events := nats.MustNewSubscriber(nats.WithTopics("events"), - nats.WithNatsURL("nats://connection"), nats.WithGroupName(`group`)) - nc.Register("events", events) - nc.Register("refresh", interval.NewSubscriber(time.Minute * 5)) - // Add new receiver to process the stream "events" + // Create a NATS subscriber + eventsSubscriber := nats.MustNewSubscriber( + nats.WithTopics("events"), + nats.WithNatsURL("nats://hostname:4222"), + nats.WithGroupName("group"), + ) + nc.Register("events", eventsSubscriber) + + // Optional: Create a time interval subscriber (e.g., for periodic tasks) + refreshSubscriber := interval.NewSubscriber(5 * time.Minute) + nc.Register("refresh", refreshSubscriber) + + // Subscribe to the "events" stream nc.Subscribe("events", func(msg nc.Message) error { - fmt.Printf("%v\n", msg.Data()) + // Process the received message + fmt.Printf("Received message: %v\n", msg.Data()) + + // Acknowledge the message if necessary return msg.Ack() }) - // Add new time interval receiver to refresh the data every 5 minutes + // Subscribe to the "refresh" stream for periodic tasks nc.Subscribe("refresh", func(msg nc.Message) error { - return db.Reload() + // Perform your periodic task here + fmt.Println("Performing periodic refresh") + return msg.Ack() }) - // Run subscriber listeners + // Start listening for messages nc.Listen(ctx) } ``` ## TODO -- [ ] Add support Amazon SQS queue -- [X] Add support Redis queue -- [ ] Add support RabbitMQ queue -- [ ] Add support MySQL notifications queue -- [X] Add support PostgreSQL notifications queue -- [X] ~~Remove metrics from the queue (DEPRECATED)~~ -- [X] Add support NATS & NATS stream -- [X] Add support kafka queue -- [X] Add support native GO chanels -- [X] Add support native GO time interval +- [ ] Add support for **Amazon SQS** +- [x] Add support for **Redis** queue +- [ ] Add support for **RabbitMQ** +- [ ] Add support for **MySQL notifications** +- [x] Add support for **PostgreSQL notifications** +- [x] ~~Remove deprecated metrics from the queue~~ +- [x] Add support for **NATS & NATS Streaming** +- [x] Add support for **Kafka** queue +- [x] Add support for native **Go channels** +- [x] Add support for **Time Interval Execution** + +## License + +NotificationCenter is licensed under the [Apache 2.0 License](LICENSE). + +--- + +By using NotificationCenter, you can focus on building the core functionality of your application without worrying about the intricacies of different messaging infrastructures. Feel free to contribute to the project or report any issues you encounter. diff --git a/go.mod b/go.mod index 400e3b7..849ded1 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,8 @@ module github.com/geniusrabbit/notificationcenter/v2 -go 1.22 +go 1.22.0 + +toolchain go1.23.1 require ( github.com/IBM/sarama v1.43.3 @@ -36,20 +38,20 @@ require ( github.com/jcmturner/gofork v1.7.6 // indirect github.com/jcmturner/gokrb5/v8 v8.4.4 // indirect github.com/jcmturner/rpc/v2 v2.0.3 // indirect - github.com/klauspost/compress v1.17.9 // indirect + github.com/klauspost/compress v1.17.10 // indirect github.com/kr/text v0.2.0 // indirect - github.com/nats-io/nats-server/v2 v2.10.18 // indirect + github.com/nats-io/nats-server/v2 v2.10.21 // indirect github.com/nats-io/nats-streaming-server v0.25.6 // indirect github.com/nats-io/nkeys v0.4.7 // indirect github.com/nats-io/nuid v1.0.1 // indirect github.com/pierrec/lz4/v4 v4.1.21 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect - github.com/rogpeppe/go-internal v1.12.0 // indirect + github.com/rogpeppe/go-internal v1.13.1 // indirect github.com/yuin/gopher-lua v1.1.1 // indirect - golang.org/x/crypto v0.26.0 // indirect - golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 // indirect - golang.org/x/net v0.28.0 // indirect - golang.org/x/sys v0.24.0 // indirect + golang.org/x/crypto v0.27.0 // indirect + golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect + golang.org/x/net v0.29.0 // indirect + golang.org/x/sys v0.25.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index b096be1..3290db0 100644 --- a/go.sum +++ b/go.sum @@ -74,8 +74,8 @@ github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZ github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= -github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.10 h1:oXAz+Vh0PMUvJczoi+flxpnBEPxoER1IaAnU/NMPtT0= +github.com/klauspost/compress v1.17.10/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -90,8 +90,8 @@ github.com/minio/highwayhash v1.0.3 h1:kbnuUMoHYyVl7szWjSxJnxw11k2U709jqFPPmIUyD github.com/minio/highwayhash v1.0.3/go.mod h1:GGYsuwP/fPD6Y9hMiXuapVvlIUEhFhMTh0rxU3ik1LQ= github.com/nats-io/jwt/v2 v2.5.8 h1:uvdSzwWiEGWGXf+0Q+70qv6AQdvcvxrv9hPM0RiPamE= github.com/nats-io/jwt/v2 v2.5.8/go.mod h1:ZdWS1nZa6WMZfFwwgpEaqBV8EPGVgOTDHN/wTbz0Y5A= -github.com/nats-io/nats-server/v2 v2.10.18 h1:tRdZmBuWKVAFYtayqlBB2BuCHNGAQPvoQIXOKwU3WSM= -github.com/nats-io/nats-server/v2 v2.10.18/go.mod h1:97Qyg7YydD8blKlR8yBsUlPlWyZKjA7Bp5cl3MUE9K8= +github.com/nats-io/nats-server/v2 v2.10.21 h1:gfG6T06wBdI25XyY2IsauarOc2srWoFxxfsOKjrzoRA= +github.com/nats-io/nats-server/v2 v2.10.21/go.mod h1:I1YxSAEWbXCfy0bthwvNb5X43WwIWMz7gx5ZVPDr5Rc= github.com/nats-io/nats-streaming-server v0.25.6 h1:8OBRaIl64u+DFvZYpF50RRzwG/yLcJZL0R7VMc7tp4Y= github.com/nats-io/nats-streaming-server v0.25.6/go.mod h1:LEcu6uGSDBB4O/IBUsDBHYk/O0K7XZza8nMjCIXicLk= github.com/nats-io/nats.go v1.22.1/go.mod h1:tLqubohF7t4z3du1QDPYJIQQyhb4wl6DhjxEajSI7UA= @@ -116,8 +116,8 @@ github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5X github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/redis/go-redis/v9 v9.6.1 h1:HHDteefn6ZkTtY5fGUE8tj8uy85AHk6zP7CpzIAM0y4= github.com/redis/go-redis/v9 v9.6.1/go.mod h1:0C0c6ycQsdpVNQpxb1njEQIqkx5UcsM8FJCQLgE9+RA= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -144,10 +144,10 @@ golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= -golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 h1:kx6Ds3MlpiUHKj7syVnbp57++8WpuKPcR5yjLBjvLEA= -golang.org/x/exp v0.0.0-20240823005443-9b4947da3948/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= +golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= +golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -163,8 +163,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -183,8 +183,8 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= @@ -194,8 +194,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= -golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= +golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= diff --git a/redis/options.go b/redis/options.go index 0133318..eb8889d 100644 --- a/redis/options.go +++ b/redis/options.go @@ -103,6 +103,7 @@ func WithRedisURL(urlString string) Option { opt.RedisOptions = &redis.Options{ Network: network, Addr: u.Host, + Username: u.User.Username(), Password: password, DB: dbNum, ClientName: query.Get("client_name"),