func DropSecondaryIndex(indexName, bucketName, server string) error { log.Printf("Dropping the secondary index %v", indexName) client, e := CreateClient(server, "2itest") if e != nil { return e } defer client.Close() indexes, err := client.Refresh() tc.HandleError(err, "Error while listing the secondary indexes") for _, index := range indexes { defn := index.Definition if (defn.Name == indexName) && (defn.Bucket == bucketName) { start := time.Now() e := client.DropIndex(uint64(defn.DefnId)) elapsed := time.Since(start) if e == nil { log.Printf("Index dropped") tc.LogPerfStat("DropIndex", elapsed) } else { return e } } } return nil }
// Todo: Remove this function and update functional tests to use BuildIndexes func BuildIndex(indexName, bucketName, server string, indexActiveTimeoutSeconds int64) error { client, e := CreateClient(server, "2itest") if e != nil { return e } defer client.Close() defnID, _ := GetDefnID(client, bucketName, indexName) start := time.Now() err := client.BuildIndexes([]uint64{defnID}) time.Sleep(2 * time.Second) // This wait is required for index state to get updated from error to initial, for example if err == nil { log.Printf("Build the deferred index %v. Waiting for the index to become active", indexName) e := WaitTillIndexActive(defnID, client, indexActiveTimeoutSeconds) if e != nil { return e } else { elapsed := time.Since(start) tc.LogPerfStat("BuildIndex", elapsed) return nil } } return err }
func Lookup(indexName, bucketName, server string, values []interface{}, distinct bool, limit int64, consistency c.Consistency, vector *qc.TsConsistency) (tc.ScanResponse, error) { var scanErr error scanErr = nil // ToDo: Create a client pool client, e := CreateClient(server, "2itest") if e != nil { return nil, e } defer client.Close() defnID, _ := GetDefnID(client, bucketName, indexName) scanResults := make(tc.ScanResponse) start := time.Now() connErr := client.Lookup( defnID, []c.SecondaryKey{values}, distinct, limit, consistency, vector, func(response qc.ResponseReader) bool { if err := response.Error(); err != nil { scanErr = err return false } else if skeys, pkeys, err := response.GetEntries(); err != nil { scanErr = err return false } else { for i, skey := range skeys { primaryKey := string(pkeys[i]) if _, keyPresent := scanResults[primaryKey]; keyPresent { // Duplicate primary key found tc.HandleError(err, "Duplicate primary key found in the scan results: "+primaryKey) } else { scanResults[primaryKey] = skey } } return true } return false }) elapsed := time.Since(start) if connErr != nil { log.Printf("Connection error in Scan occured: %v", connErr) return scanResults, connErr } else if scanErr != nil { return scanResults, scanErr } tc.LogPerfStat("Lookup", elapsed) return scanResults, nil }
// Creates an index and waits for it to become active func CreateSecondaryIndex( indexName, bucketName, server, whereExpr string, indexFields []string, isPrimary bool, with []byte, skipIfExists bool, indexActiveTimeoutSeconds int64, client *qc.GsiClient) error { if client == nil { c, e := CreateClient(server, "2itest") if e != nil { return e } client = c defer client.Close() } indexExists := IndexExistsWithClient(indexName, bucketName, server, client) if skipIfExists == true && indexExists == true { return nil } var secExprs []string if isPrimary == false { for _, indexField := range indexFields { expr, err := n1ql.ParseExpression(indexField) if err != nil { log.Printf("Creating index %v. Error while parsing the expression (%v) : %v", indexName, indexField, err) } secExprs = append(secExprs, expression.NewStringer().Visit(expr)) } } using := "gsi" exprType := "N1QL" partnExp := "" start := time.Now() defnID, err := client.CreateIndex(indexName, bucketName, using, exprType, partnExp, whereExpr, secExprs, isPrimary, with) if err == nil { log.Printf("Created the secondary index %v. Waiting for it become active", indexName) e := WaitTillIndexActive(defnID, client, indexActiveTimeoutSeconds) if e != nil { return e } else { elapsed := time.Since(start) tc.LogPerfStat("CreateAndBuildIndex", elapsed) return nil } } return err }
func RangeWithClient(indexName, bucketName, server string, low, high []interface{}, inclusion uint32, distinct bool, limit int64, consistency c.Consistency, vector *qc.TsConsistency, client *qc.GsiClient) (tc.ScanResponse, error) { var scanErr error scanErr = nil defnID, _ := GetDefnID(client, bucketName, indexName) scanResults := make(tc.ScanResponse) start := time.Now() connErr := client.Range( defnID, c.SecondaryKey(low), c.SecondaryKey(high), qc.Inclusion(inclusion), distinct, limit, consistency, vector, func(response qc.ResponseReader) bool { if err := response.Error(); err != nil { scanErr = err return false } else if skeys, pkeys, err := response.GetEntries(); err != nil { scanErr = err return false } else { for i, skey := range skeys { primaryKey := string(pkeys[i]) if _, keyPresent := scanResults[primaryKey]; keyPresent { // Duplicate primary key found tc.HandleError(err, "Duplicate primary key found in the scan results: "+primaryKey) } else { scanResults[primaryKey] = skey } } return true } return false }) elapsed := time.Since(start) if connErr != nil { log.Printf("Connection error in Scan occured: %v", connErr) return scanResults, connErr } else if scanErr != nil { return scanResults, scanErr } tc.LogPerfStat("Range", elapsed) return scanResults, nil }
func Range(indexName, bucketName, server string, low, high []interface{}, inclusion uint32, distinct bool, limit int64, consistency c.Consistency, vector *qc.TsConsistency) (tc.ScanResponse, error) { var scanErr error scanErr = nil var previousSecKey value.Value // ToDo: Create a client pool client, e := CreateClient(server, "2itest") if e != nil { return nil, e } defer client.Close() defnID, _ := GetDefnID(client, bucketName, indexName) scanResults := make(tc.ScanResponse) start := time.Now() connErr := client.Range( defnID, c.SecondaryKey(low), c.SecondaryKey(high), qc.Inclusion(inclusion), distinct, limit, consistency, vector, func(response qc.ResponseReader) bool { if err := response.Error(); err != nil { scanErr = err return false } else if skeys, pkeys, err := response.GetEntries(); err != nil { scanErr = err return false } else { for i, skey := range skeys { primaryKey := string(pkeys[i]) if _, keyPresent := scanResults[primaryKey]; keyPresent { // Duplicate primary key found tc.HandleError(err, "Duplicate primary key found in the scan results: "+primaryKey) } else { // Test collation only if CheckCollation is true if CheckCollation == true && len(skey) > 0 { secVal := skey2Values(skey)[0] if previousSecKey == nil { previousSecKey = secVal } else { if secVal.Collate(previousSecKey) < 0 { errMsg := "Collation check failed. Previous Sec key > Current Sec key" scanErr = errors.New(errMsg) return false } } } scanResults[primaryKey] = skey } } return true } return false }) elapsed := time.Since(start) if connErr != nil { log.Printf("Connection error in Scan occured: %v", connErr) return scanResults, connErr } else if scanErr != nil { return scanResults, scanErr } tc.LogPerfStat("Range", elapsed) return scanResults, nil }