Created
June 10, 2021 11:04
-
-
Save meysampg/e895e8fd181d6af58c8e97a02fad6e1a to your computer and use it in GitHub Desktop.
Scan a CQLSh query in golang with unknown fields
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package query | |
// THIS CODE IS NOT SUITABLE FOR USING IN THE PRODUCTION. | |
// YOU SHOULD TAKE CARE ABOUT DB TYPES AND ERROR HANDLING. | |
// ANOTHER OPTIMIZATION CAN BE IN CHANGING []map[string]interface{} | |
// TO map[string][]interface{} | |
import ( | |
"time" | |
"github.com/gocql/gocql" | |
log "github.com/sirupsen/logrus" | |
) | |
func runQuery(session *gocql.Session, query string, pageSize int) []map[string]interface{} { | |
var pageState []byte | |
result := make([]map[string]interface{}, 0) | |
for { | |
iter := session.Query(query).PageSize(pageSize).PageState(pageState).Iter() | |
nextPageState := iter.PageState() | |
scanner := iter.Scanner() | |
columns := iter.Columns() | |
numCol := len(columns) | |
values := make([]interface{}, numCol) | |
for scanner.Next() { | |
r := make(map[string]interface{}) | |
for i := range columns { | |
values[i] = getDefaultType(columns[i].TypeInfo.Type()) | |
} | |
err := scanner.Scan(values...) | |
if err != nil { | |
log.Error(err) | |
} | |
for i := range columns { | |
r[columns[i].Name] = getDirectValue(values[i]) | |
} | |
result = append(result, r) | |
} | |
err := scanner.Err() | |
if err != nil { | |
log.Fatal(err) | |
} | |
if len(nextPageState) == 0 { | |
break | |
} | |
pageState = nextPageState | |
err = iter.Close() | |
if err != nil { | |
log.Error(err) | |
} | |
} | |
return result | |
} | |
// Add more types if it's needed | |
func getDefaultType(typ gocql.Type) interface{} { | |
switch typ { | |
case gocql.TypeBigInt, gocql.TypeInt: | |
return new(int64) | |
case gocql.TypeBlob: | |
return new(string) | |
case gocql.TypeTimestamp: | |
return new(time.Time) | |
default: | |
return new(string) | |
} | |
} | |
// Add type casts for types added on previous method | |
func getDirectValue(v interface{}) interface{} { | |
switch v.(type) { | |
case *int64: | |
return *v.(*int64) | |
case *string: | |
return *v.(*string) | |
case *time.Time: | |
return *v.(*time.Time) | |
default: | |
return v | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment