Elasticsearch CreateIndex() not enough arguments - elasticsearch

I am trying to use Elasticsearch for GO with this well-known repo
However, when I am trying to create an index (docs, and also given as an example here):
// Define an elastic client
client, err := elastic.NewClient(elastic.SetURL("host1"))
if err != nil {
client, err := elastic.NewClient(elastic.SetURL("host2"))
if err != nil {
fmt.Println("Error when connecting Elasticsearch host");
}
}
// Create an index
_, err = client.CreateIndex("events").Do()
if err != nil {
fmt.Println("Error when creating Elasticsearch index");
panic(err)
}
I got the following error, which I do not understand:
not enough arguments in call to client.CreateIndex("events").Do
Why is that? What do I miss here?

The IndicesCreateService.Do() function expects a context.Context to be passed.
So, you need to import "golang.org/x/net/context" and then change your call to this:
import (
... your other imports...
"golang.org/x/net/context"
)
...
_, err := client.CreateIndex("events").Do(context.TODO())
^
|
add this
You can also check the indices_create_test.go test case in order to see how it's done.

Related

How to define a connect to DB function in golang using gorm

Good morning,
I am new to golang. I am creating following connect to DB function:
func ConnectDatabase(db gorm.Dialector, gorm.Config gorm.Option) *gorm.DB{
db, err := gorm.Open(db, gormConfig)
if err != nil {
log.Fatal(err)
}
return db
}
It gives me an error on Open: cannot use gorm.Open(db, gormConfig)(value of type *gorm.DB) as gorm.Dialector value in assignment: *gorm.DB does not implement gorm.Dialector
The reason I create the function with two parameteres is because i want to wright the test on it, and need to pass test parameters to it
My test code looks like it:
func TestDbConnect(t *testing.T){
dbFile, err := os.CreateTemp("", "sample_db"
if err != nil{
t.Fatal(err)
}
sqlOpen := sqlite.Open(dbFile.Name())
gormConfig := &gorm.Config{}
conn, err := sqlOpen, gormConfig
}
Would really appreciate an advice on how to define my function correctly and if my test function makes sense
You have some improper function signature ,in parameters .I have fixed your code .Now you can use it
package main
import (
"fmt"
"log"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
func ConnectDatabase(db gorm.Dialector, config *gorm.Config, option gorm.Option) (*gorm.DB,err) {
db1, err := gorm.Open(db, config)
if err != nil {
return nil,err // return nil and error here
}
return db1,nil
}
func main() {
sql := sqlite.Open("test.db")
db := ConnectDatabase(sql, &gorm.Config{}, nil)
fmt.Println("Hello, World!", db)
}
Points -
1- Dialector is an interface of gorm
2- sqlite.Open("test.db") returns Dialector interface
Your test would look something like this
func TestDbConnect(t *testing.T){
dbFile, err := os.CreateTemp("", "sample_db"
if err != nil{
t.Fatal(err)
}
sqlOpen := sqlite.Open(dbFile.Name())
db,err := ConnectDatabase(sqlOpen, &gorm.Config{}, nil)
// handle error and test pass case
}
Also don't make function local variable name as parameter name,this may cause variable shadowing see here as you are having err variable as new one in this line
db, err := gorm.Open(db, gormConfig)
so go complier was not giving error.

GCP - Remove Obsolete Buckets

GCP - Remove Obsolete Buckets
Remove Obsolete Buckets in GCP in golang
How can I implement this thing in golang ?
You may try to delete the bucket through BucketHandle.Delete
import (
"context"
"cloud.google.com/go/storage"
)
func main() {
ctx := context.Background()
client, err := storage.NewClient(ctx)
if err != nil {
// TODO: handle error.
}
if err := client.Bucket("my-bucket").Delete(ctx); err != nil {
// TODO: handle error.
}
}

Testing NATS-streaming in Kubernetes with minimal effort

I wanted to test a very basic application for NATS-streaming on Kubernetes. To do so, I followed the commands from the official NATS-docs.
It basically comes down to running
kubectl apply -f https://raw.githubusercontent.com/nats-io/k8s/master/nats-server/single-server-nats.yml
kubectl apply -f https://raw.githubusercontent.com/nats-io/k8s/master/nats-streaming-server/single-server-stan.yml
in a terminal with access to the cluster (it's a kind-cluster in my case).
I used stan.go as the NATS-streaming-client. Here is the code I tried to connect to the NATS-streaming-server:
package main
import stan "github.com/nats-io/stan.go"
func main() {
sc, err := stan.Connect("stan", "test-client")
if err != nil {
panic(err)
}
if err := sc.Publish("test-subject", []byte("This is a test-message!")); err != nil {
panic(err)
}
}
and this is the error I'm getting:
panic: nats: no servers available for connection
goroutine 1 [running]:
main.main()
/Users/thilt/tmp/main.go:9 +0x15d
exit status 2
so I think another name was used for the cluster or something. If I use the provided example with nats-box from the docs.nats-link above, it also doesn't work! Where did I go wrong here?
I will happily provide more information, if needed.
There is a great example in stan.go docs:
// Connect to NATS
nc, err := nats.Connect(URL, opts...)
if err != nil {
log.Fatal(err)
}
defer nc.Close()
sc, err := stan.Connect(clusterID, clientID, stan.NatsConn(nc))
if err != nil {
log.Fatalf("Can't connect: %v.\nMake sure a NATS Streaming Server is running at: %s", err, URL)
}
defer sc.Close()
Your error happens because by default stan connects to localhost address (source code):
// DefaultNatsURL is the default URL the client connects to
DefaultNatsURL = "nats://127.0.0.1:4222"
Notice that povided above example overwrite this default connection.
Stan source code is short and easy to analyze. I really recommend you to try to analyze it and figure out what it does.
Now let's put it all together; here is a working example:
package main
import (
nats "github.com/nats-io/nats.go"
stan "github.com/nats-io/stan.go"
)
func main() {
// Create a NATS connection
nc, err := nats.Connect("nats://nats:4222")
if err != nil {
panic(err)
}
// Then pass it to the stan.Connect() call.
sc, err := stan.Connect("stan", "me", stan.NatsConn(nc))
if err != nil {
panic(err)
}
if err := sc.Publish("test-subject", []byte("This is a test-message!")); err != nil {
panic(err)
}
}

golang bigquery docs specify done operator but it generates a compile error

So the docs here state specifically to use iterator.Done:
Next loads the next row into dst. Its return value is iterator.Done if there are no more results. Once Next returns iterator.Done, all subsequent calls will return iterator.Done.
However if I attempt to use Done it generates a compiler error. Indeed, Done is not defined on the RowIterator docs here.
My code (almost identical to the docs):
it, err := job.Read(ctx)
if err != nil {
fmt.Println(err)
}
for {
var rec MyType
err := it.Next(&rec)
// the docs say to use Done, but it provides an error
if err == it.Done {
break
}
if err != nil {
fmt.Println(err)
}
rows = append(rows, rec)
}
When I try to build it, I get:
./test.go:94:15: it.Done undefined (type *"cloud.google.com/go/bigquery".RowIterator has no field or method Done)
What am I missing?
iterator.Done is a variable defined in the iterator package. So replace it.Done with iterator.Done. This is shown in this example:
package main
import (
"cloud.google.com/go/bigquery"
"context"
"fmt"
"google.golang.org/api/iterator"
)
func main() {
ctx := context.Background()
client, err := bigquery.NewClient(ctx, "project-id")
if err != nil {
// TODO: Handle error.
}
q := client.Query("select name, num from t1")
it, err := q.Read(ctx)
if err != nil {
// TODO: Handle error.
}
for {
var row []bigquery.Value
err := it.Next(&row)
if err == iterator.Done {
break
}
if err != nil {
// TODO: Handle error.
}
fmt.Println(row)
}
}
You have confused between the iterator returned from the Job.Read call i.e. the RowIterator and the generic Google API iterator in https://pkg.go.dev/google.golang.org/api/iterator
You should check the return value from the latter i.e. err == iterator.Done to check if the the iteration is complete. The sample codes under the documentation has useful examples explained - https://github.com/GoogleCloudPlatform/golang-samples/tree/master/bigquery

Google Sheets API: golang BatchUpdateValuesRequest

I'm trying to follow the Google Sheets API quickstart here:
https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/batchUpdate
(scroll down to "Examples" then click "GO")
This is how I tried to update a spreadsheet:
package main
// BEFORE RUNNING:
// ---------------
// 1. If not already done, enable the Google Sheets API
// and check the quota for your project at
// https://console.developers.google.com/apis/api/sheets
// 2. Install and update the Go dependencies by running `go get -u` in the
// project directory.
import (
"errors"
"fmt"
"log"
"net/http"
"golang.org/x/net/context"
"google.golang.org/api/sheets/v4"
)
func main() {
ctx := context.Background()
c, err := getClient(ctx)
if err != nil {
log.Fatal(err)
}
sheetsService, err := sheets.New(c)
if err != nil {
log.Fatal(err)
}
// The ID of the spreadsheet to update.
spreadsheetId := "1diQ943LGMDNkbCRGG4VqgKZdzyanCtT--V8o7r6kCR0"
var jsonPayloadVar []string
monthVar := "Apr"
thisCellVar := "A26"
thisLinkVar := "http://test.url"
jsonRackNumberVar := "\"RACKNUM01\""
jsonPayloadVar = append(jsonPayloadVar, fmt.Sprintf("(\"range\": \"%v!%v\", \"values\": [[\"%v,%v)\"]]),", monthVar, thisCellVar, thisLinkVar, jsonRackNumberVar))
rb := &sheets.BatchUpdateValuesRequest{"ValueInputOption": "USER_ENTERED", "data": jsonPayloadVar}
resp, err := sheetsService.Spreadsheets.Values.BatchUpdate(spreadsheetId, rb).Context(ctx).Do()
if err != nil {
log.Fatal(err)
}
fmt.Printf("%#v\n", resp)
}
func getClient(ctx context.Context) (*http.Client, error) {
// https://developers.google.com/sheets/quickstart/go#step_3_set_up_the_sample
//
// Authorize using the following scopes:
// sheets.DriveScope
// sheets.DriveFileScope
sheets.SpreadsheetsScope
return nil, errors.New("not implemented")
}
Output:
hello.go:43: invalid field name "ValueInputOption" in struct initializer
hello.go:43: invalid field name "data" in struct initializer
hello.go:58: sheets.SpreadsheetsScope evaluated but not used
There are 2 things that aren't working:
It's not obvious how to enter the fields into variable rb
I need to use sheets.SpreadsheetsScope
Can anyone provide a working example that does a BatchUpdate?
References:
This article shows how to do an update that is not a BatchUpdate: Golang google sheets API V4 - Write/Update example?
Google's API reference - see the ValueInputOption section starting at line 1437: https://github.com/google/google-api-go-client/blob/master/sheets/v4/sheets-gen.go
This article shows how to do a BatchUpdate in Java: Write data to Google Sheet using Google Sheet API V4 - Java Sample Code
How about the following sample script? This is a simple sample script for updating sheet on Spreadsheet. So if you want to do various update, please modify it. The detail of parameters for spreadsheets.values.batchUpdate is here.
Flow :
At first, in ordet to use the link in your question, please use Go Quickstart. In my sample script, the script was made using the Quickstart.
The flow to use this sample script is as follows.
For Go Quickstart, please do Step 1 and Step 2.
Please put client_secret.json to the same directory with my sample script.
Copy and paste my sample script, and create it as new script file.
Run the script.
When Go to the following link in your browser then type the authorization code: is shown on your terminal, please copy the URL and paste to your browser. And then, please authorize and get code.
Put the code to the terminal.
When Done. is displayed, it means that the update of spreadsheet is done.
Request body :
For Spreadsheets.Values.BatchUpdate, BatchUpdateValuesRequest is required as one of parameters. In this case, the range, values and so on that you want to update are included in BatchUpdateValuesRequest. The detail information of this BatchUpdateValuesRequest can be seen at godoc. When it sees BatchUpdateValuesRequest, Data []*ValueRange can be seen. Here, please be carefull that Data is []*ValueRange. Also ValueRange can be seen at godoc. You can see MajorDimension, Range and Values in ValueRange.
When above infomation is reflected to the script, the script can be modified as follows.
Sample script :
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"golang.org/x/net/context"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
"google.golang.org/api/sheets/v4"
)
// getClient uses a Context and Config to retrieve a Token
// then generate a Client. It returns the generated Client.
func getClient(ctx context.Context, config *oauth2.Config) *http.Client {
cacheFile := "./go-quickstart.json"
tok, err := tokenFromFile(cacheFile)
if err != nil {
tok = getTokenFromWeb(config)
saveToken(cacheFile, tok)
}
return config.Client(ctx, tok)
}
// getTokenFromWeb uses Config to request a Token.
// It returns the retrieved Token.
func getTokenFromWeb(config *oauth2.Config) *oauth2.Token {
authURL := config.AuthCodeURL("state-token", oauth2.AccessTypeOffline)
fmt.Printf("Go to the following link in your browser then type the "+
"authorization code: \n%v\n", authURL)
var code string
if _, err := fmt.Scan(&code); err != nil {
log.Fatalf("Unable to read authorization code %v", err)
}
tok, err := config.Exchange(oauth2.NoContext, code)
if err != nil {
log.Fatalf("Unable to retrieve token from web %v", err)
}
return tok
}
// tokenFromFile retrieves a Token from a given file path.
// It returns the retrieved Token and any read error encountered.
func tokenFromFile(file string) (*oauth2.Token, error) {
f, err := os.Open(file)
if err != nil {
return nil, err
}
t := &oauth2.Token{}
err = json.NewDecoder(f).Decode(t)
defer f.Close()
return t, err
}
func saveToken(file string, token *oauth2.Token) {
fmt.Printf("Saving credential file to: %s\n", file)
f, err := os.Create(file)
if err != nil {
log.Fatalf("Unable to cache oauth token: %v", err)
}
defer f.Close()
json.NewEncoder(f).Encode(token)
}
type body struct {
Data struct {
Range string `json:"range"`
Values [][]string `json:"values"`
} `json:"data"`
ValueInputOption string `json:"valueInputOption"`
}
func main() {
ctx := context.Background()
b, err := ioutil.ReadFile("client_secret.json")
if err != nil {
log.Fatalf("Unable to read client secret file: %v", err)
}
config, err := google.ConfigFromJSON(b, "https://www.googleapis.com/auth/spreadsheets")
if err != nil {
log.Fatalf("Unable to parse client secret file to config: %v", err)
}
client := getClient(ctx, config)
sheetsService, err := sheets.New(client)
if err != nil {
log.Fatalf("Unable to retrieve Sheets Client %v", err)
}
spreadsheetId := "### spreadsheet ID ###"
rangeData := "sheet1!A1:B3"
values := [][]interface{}{{"sample_A1", "sample_B1"}, {"sample_A2", "sample_B2"}, {"sample_A3", "sample_A3"}}
rb := &sheets.BatchUpdateValuesRequest{
ValueInputOption: "USER_ENTERED",
}
rb.Data = append(rb.Data, &sheets.ValueRange{
Range: rangeData,
Values: values,
})
_, err = sheetsService.Spreadsheets.Values.BatchUpdate(spreadsheetId, rb).Context(ctx).Do()
if err != nil {
log.Fatal(err)
}
fmt.Println("Done.")
}
Result :
References :
The detail infomation of spreadsheets.values.batchUpdate is here.
The detail infomation of Go Quickstart is here.
The detail infomation of BatchUpdateValuesRequest is here.
The detail infomation of ValueRange is here.
If I misunderstand your question, I'm sorry.

Resources