github.com/cayleygraph/cayley@v0.7.7/graph/gaedatastore/config.go (about) 1 // Copyright 2014 The Cayley Authors. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package gaedatastore 16 17 import ( 18 "encoding/json" 19 "fmt" 20 "os" 21 "strconv" 22 "time" 23 ) 24 25 // Config defines the behavior of cayley database instances. 26 type Config struct { 27 DatabaseType string 28 DatabasePath string 29 DatabaseOptions map[string]interface{} 30 ReplicationType string 31 ReplicationOptions map[string]interface{} 32 ListenHost string 33 ListenPort string 34 ReadOnly bool 35 Timeout time.Duration 36 LoadSize int 37 } 38 39 type config struct { 40 DatabaseType string `json:"database"` 41 DatabasePath string `json:"db_path"` 42 DatabaseOptions map[string]interface{} `json:"db_options"` 43 ReplicationType string `json:"replication"` 44 ReplicationOptions map[string]interface{} `json:"replication_options"` 45 ListenHost string `json:"listen_host"` 46 ListenPort string `json:"listen_port"` 47 ReadOnly bool `json:"read_only"` 48 Timeout duration `json:"timeout"` 49 LoadSize int `json:"load_size"` 50 } 51 52 func (c *Config) UnmarshalJSON(data []byte) error { 53 var t config 54 err := json.Unmarshal(data, &t) 55 if err != nil { 56 return err 57 } 58 *c = Config{ 59 DatabaseType: t.DatabaseType, 60 DatabasePath: t.DatabasePath, 61 DatabaseOptions: t.DatabaseOptions, 62 ReplicationType: t.ReplicationType, 63 ReplicationOptions: t.ReplicationOptions, 64 ListenHost: t.ListenHost, 65 ListenPort: t.ListenPort, 66 ReadOnly: t.ReadOnly, 67 Timeout: time.Duration(t.Timeout), 68 LoadSize: t.LoadSize, 69 } 70 return nil 71 } 72 73 func (c *Config) MarshalJSON() ([]byte, error) { 74 return json.Marshal(config{ 75 DatabaseType: c.DatabaseType, 76 DatabasePath: c.DatabasePath, 77 DatabaseOptions: c.DatabaseOptions, 78 ReplicationType: c.ReplicationType, 79 ReplicationOptions: c.ReplicationOptions, 80 ListenHost: c.ListenHost, 81 ListenPort: c.ListenPort, 82 ReadOnly: c.ReadOnly, 83 Timeout: duration(c.Timeout), 84 LoadSize: c.LoadSize, 85 }) 86 } 87 88 // duration is a time.Duration that satisfies the 89 // json.UnMarshaler and json.Marshaler interfaces. 90 type duration time.Duration 91 92 // UnmarshalJSON unmarshals a duration according to the following scheme: 93 // * If the element is absent the duration is zero. 94 // * If the element is parsable as a time.Duration, the parsed value is kept. 95 // * If the element is parsable as a number, that number of seconds is kept. 96 func (d *duration) UnmarshalJSON(data []byte) error { 97 if len(data) == 0 { 98 *d = 0 99 return nil 100 } 101 text := string(data) 102 t, err := time.ParseDuration(text) 103 if err == nil { 104 *d = duration(t) 105 return nil 106 } 107 i, err := strconv.ParseInt(text, 10, 64) 108 if err == nil { 109 *d = duration(time.Duration(i) * time.Second) 110 return nil 111 } 112 // This hack is to get around strconv.ParseFloat 113 // not handling e-notation for integers. 114 f, err := strconv.ParseFloat(text, 64) 115 *d = duration(time.Duration(f) * time.Second) 116 return err 117 } 118 119 func (d *duration) MarshalJSON() ([]byte, error) { 120 return []byte(fmt.Sprintf("%q", *d)), nil 121 } 122 123 // Load reads a JSON-encoded config contained in the given file. A zero value 124 // config is returned if the filename is empty. 125 func LoadConf(file string) (*Config, error) { 126 config := &Config{} 127 if file == "" { 128 return config, nil 129 } 130 f, err := os.Open(file) 131 if err != nil { 132 return nil, fmt.Errorf("could not open config file %q: %v", file, err) 133 } 134 defer f.Close() 135 136 dec := json.NewDecoder(f) 137 err = dec.Decode(config) 138 if err != nil { 139 return nil, fmt.Errorf("could not parse config file %q: %v", file, err) 140 } 141 return config, nil 142 }