| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310 |
- package qconf
- //#cgo LDFLAGS: -L/usr/local/qconf/lib/ -lm
- /*
- #cgo LDFLAGS: -lqconf -lm
- #include <stdlib.h>
- #include <stdio.h>
- struct string_vector
- {
- int count; // the number of services
- char **data; // the array of services
- };
- typedef struct string_vector string_vector_t;
- typedef struct qconf_node
- {
- char *key;
- char *value;
- } qconf_node;
- typedef struct qconf_batch_nodes
- {
- int count;
- qconf_node *nodes;
- } qconf_batch_nodes;
- int qconf_init();
- int qconf_destroy();
- int init_string_vector(string_vector_t *nodes);
- int destroy_string_vector(string_vector_t *nodes);
- int init_qconf_batch_nodes(qconf_batch_nodes *bnodes);
- int destroy_qconf_batch_nodes(qconf_batch_nodes *bnodes);
- int qconf_get_conf(const char *path, char *buf, int buf_len, const char *idc);
- int qconf_get_allhost(const char *path, string_vector_t *nodes, const char *idc);
- int qconf_get_host(const char *path, char *buf, int buf_len, const char *idc);
- int qconf_get_batch_conf(const char *path, qconf_batch_nodes *bnodes, const char *idc);
- int qconf_get_batch_keys(const char *path, string_vector_t *nodes, const char *idc);
- */
- import "C"
- import (
- "errors"
- "fmt"
- "reflect"
- "unsafe"
- )
- type Errno int
- func (e Errno) Error() string {
- s := errText[e]
- if s == "" {
- return fmt.Sprintf("unknown errno %d", int(e))
- }
- return s
- }
- var errText = map[Errno]string{
- -1: "Execute failure!",
- 1: "Error parameter!",
- 2: "Failed to malloc memory!",
- 3: "Failed to set share memory!",
- 4: "Failed to get zookeeper host!",
- 5: "Failed to get idc!",
- 6: "Buffer not enough!",
- 7: "Illegal data type!",
- 8: "Illegal data format!",
- 10: "Failed to find key on given idc!",
- 11: "Failed to open dump file!",
- 12: "Failed to open tmp dump file!",
- 13: "Failed to find key in dump!",
- 14: "Failed to rename dump!",
- 15: "Failed to write dump!",
- 16: "Same with the value in share memory!",
- 20: "Configure item error : out of range!",
- 21: "Configure item error : not number!",
- 22: "Configure item error : further characters exists!",
- 30: "Configure item error : invalid ip!",
- 31: "Configure item error : invalid port!",
- 40: "No message exist in message queue!",
- 41: "Length of message in the queue is too large!",
- 71: "Error hostname!",
- }
- var (
- ErrOther error = Errno(-1)
- ErrQconfParam error = Errno(1)
- ErrQconfMem error = Errno(2)
- ErrQconfTblSet error = Errno(3)
- ErrQconfGetHost error = Errno(4)
- ErrQconfGetIdc error = Errno(5)
- ErrQconfBufNotEnough error = Errno(6)
- ErrQconfDataType error = Errno(7)
- ErrQconfDataFormat error = Errno(8)
- ErrQconfNotFound error = Errno(10)
- ErrQconfOpenDump error = Errno(11)
- ErrQconfOpenTmpDump error = Errno(12)
- ErrQconfNotInDump error = Errno(13)
- ErrQconfRenameDump error = Errno(14)
- ErrQconfWriteDump error = Errno(15)
- ErrQconfSameValue error = Errno(16)
- ErrQconfOutOfRange error = Errno(20)
- ErrQconfNotNumber error = Errno(21)
- ErrQconfOtherCharacter error = Errno(22)
- ErrQconfInvalidIp error = Errno(30)
- ErrQconfInvalidPort error = Errno(31)
- ErrQconfNoMessage error = Errno(40)
- ErrQconfE2Big error = Errno(41)
- ErrQconfHostname error = Errno(71)
- )
- const (
- QCONF_DRIVER_GO_VERSION = "1.2.1"
- QCONF_CONF_BUF_INIT_MAX_LEN = 2 * 1024
- QCONF_CONF_BUF_MAX_LEN = 1024 * 1024
- QCONF_CONF_BUF_MULTIPLE = 8
- QCONF_HOST_BUF_MAX_LEN = 256
- QCONF_OK = 0
- QCONF_ERR_BUF_NOT_ENOUGH = 6
- )
- //func init(){
- // ret := C.qconf_init()
- // if QCONF_OK != ret {
- // panic(ret)
- // }
- //}
- func initQconf() error {
- ret := C.qconf_init()
- if QCONF_OK != ret {
- return errors.New(fmt.Sprintf("%v", ret))
- }
- return nil
- }
- func convertToGoSlice(nodes *C.string_vector_t) []string {
- length := int((*nodes).count)
- hdr := reflect.SliceHeader{
- Data: uintptr(unsafe.Pointer((*nodes).data)),
- Len: length,
- Cap: length,
- }
- charp_nodes := *(*[]*C.char)(unsafe.Pointer(&hdr))
- go_nodes := []string{}
- for i := 0; i < length; i++ {
- go_host := C.GoString(charp_nodes[i])
- go_nodes = append(go_nodes, go_host)
- }
- return go_nodes
- }
- func convertToGoMap(bnodes *C.qconf_batch_nodes) map[string]string {
- length := int((*bnodes).count)
- hdr := reflect.SliceHeader{
- Data: uintptr(unsafe.Pointer((*bnodes).nodes)),
- Len: length,
- Cap: length,
- }
- qconf_nodes := *(*[]C.qconf_node)(unsafe.Pointer(&hdr))
- go_nodes := map[string]string{}
- for i := 0; i < length; i++ {
- go_key := C.GoString(qconf_nodes[i].key)
- go_value := C.GoString(qconf_nodes[i].value)
- go_nodes[go_key] = go_value
- }
- return go_nodes
- }
- func GetConf(key string, idc string) (string, error) {
- c_key := C.CString(key)
- defer C.free(unsafe.Pointer(c_key))
- var ret int
- var c_ptr_value *C.char
- slice_length := QCONF_CONF_BUF_INIT_MAX_LEN
- for ret = QCONF_ERR_BUF_NOT_ENOUGH; ret == QCONF_ERR_BUF_NOT_ENOUGH && slice_length <= QCONF_CONF_BUF_MAX_LEN; slice_length *= QCONF_CONF_BUF_MULTIPLE {
- c_value := make([]C.char, slice_length)
- c_ptr_value = (*C.char)(unsafe.Pointer(&(c_value[0])))
- if idc == "" {
- ret = int(C.qconf_get_conf(c_key, c_ptr_value, C.int(slice_length), nil))
- } else {
- c_idc := C.CString(idc)
- defer C.free(unsafe.Pointer(c_idc))
- ret = int(C.qconf_get_conf(c_key, c_ptr_value, C.int(slice_length), c_idc))
- }
- }
- if QCONF_OK != ret {
- cur_err := Errno(ret)
- return "", cur_err
- }
- go_value := C.GoString(c_ptr_value)
- return go_value, nil
- }
- func GetHost(key string, idc string) (string, error) {
- c_key := C.CString(key)
- defer C.free(unsafe.Pointer(c_key))
- var c_host [QCONF_HOST_BUF_MAX_LEN]C.char
- c_ptr_host := (*C.char)(unsafe.Pointer(&(c_host[0])))
- var ret int
- if idc == "" {
- ret = int(C.qconf_get_host(c_key, c_ptr_host, QCONF_HOST_BUF_MAX_LEN, nil))
- } else {
- c_idc := C.CString(idc)
- defer C.free(unsafe.Pointer(c_idc))
- ret = int(C.qconf_get_host(c_key, c_ptr_host, QCONF_HOST_BUF_MAX_LEN, c_idc))
- }
- if QCONF_OK != ret {
- cur_err := Errno(ret)
- return "", cur_err
- }
- go_host := C.GoString(c_ptr_host)
- return go_host, nil
- }
- func GetAllHost(key string, idc string) ([]string, error) {
- c_key := C.CString(key)
- defer C.free(unsafe.Pointer(c_key))
- var nodes C.string_vector_t
- init_ret := C.init_string_vector(&nodes)
- if QCONF_OK != init_ret {
- cur_err := Errno(init_ret)
- return nil, cur_err
- }
- defer C.destroy_string_vector(&nodes)
- var ret int
- if idc == "" {
- ret = int(C.qconf_get_allhost(c_key, &nodes, nil))
- } else {
- c_idc := C.CString(idc)
- defer C.free(unsafe.Pointer(c_idc))
- ret = int(C.qconf_get_allhost(c_key, &nodes, c_idc))
- }
- if QCONF_OK != ret {
- cur_err := Errno(ret)
- return nil, cur_err
- }
- go_nodes := convertToGoSlice(&nodes)
- return go_nodes, nil
- }
- func GetBatchConf(key string, idc string) (map[string]string, error) {
- c_key := C.CString(key)
- defer C.free(unsafe.Pointer(c_key))
- var bnodes C.qconf_batch_nodes
- init_ret := C.init_qconf_batch_nodes(&bnodes)
- if QCONF_OK != init_ret {
- cur_err := Errno(init_ret)
- return nil, cur_err
- }
- defer C.destroy_qconf_batch_nodes(&bnodes)
- var ret int
- if idc == "" {
- ret = int(C.qconf_get_batch_conf(c_key, &bnodes, nil))
- } else {
- c_idc := C.CString(idc)
- defer C.free(unsafe.Pointer(c_idc))
- ret = int(C.qconf_get_batch_conf(c_key, &bnodes, c_idc))
- }
- if QCONF_OK != ret {
- cur_err := Errno(ret)
- return nil, cur_err
- }
- go_nodes := convertToGoMap(&bnodes)
- return go_nodes, nil
- }
- func GetBatchKeys(key string, idc string) ([]string, error) {
- c_key := C.CString(key)
- defer C.free(unsafe.Pointer(c_key))
- var nodes C.string_vector_t
- init_ret := C.init_string_vector(&nodes)
- if QCONF_OK != init_ret {
- cur_err := Errno(init_ret)
- return nil, cur_err
- }
- defer C.destroy_string_vector(&nodes)
- var ret int
- if idc == "" {
- ret = int(C.qconf_get_batch_keys(c_key, &nodes, nil))
- } else {
- c_idc := C.CString(idc)
- defer C.free(unsafe.Pointer(c_idc))
- ret = int(C.qconf_get_batch_keys(c_key, &nodes, c_idc))
- }
- if QCONF_OK != ret {
- cur_err := Errno(ret)
- return nil, cur_err
- }
- go_nodes := convertToGoSlice(&nodes)
- return go_nodes, nil
- }
- func Version() (string, error) {
- return QCONF_DRIVER_GO_VERSION, nil
- }
|