Answer the question
In order to leave comments, you need to log in
How to make json.Marshal/Unmarshal for complex map?
I needed to replicate map with cache to a file. It's very simple, I thought. It saves all "simple" (string, ... int) types normally, but as soon as the structure gets into the cache, problems begin. Now I have to manually encode it in json every time I add a structure to the cache (throughout the code ...). How to make the encoding of structures in json happen automatically in the replication function?
I did not succeed in zayuzat reflection.
The cache stores the map
type DB struct {
Storage map[string]interface{}
RW *sync.RWMutex
}
var storage = map[string]*DB
package cache
import (
"time"
"encoding/json"
"os"
"io/ioutil"
"log"
"sync"
)
type Replication map[string]map[string]interface{}
func ReplicationFileSystem(file string, timeRepl time.Duration) {
SelectReplication(file)
for {
time.Sleep(timeRepl)
replication(file)
}
}
func SelectReplication(file string){
log.Println("Cache replication: Start")
var replication Replication
val, err := ioutil.ReadFile(file)
if err != nil {
log.Fatal("Cache replication err: ", err)
}
err = json.Unmarshal(val, &replication)
if err != nil {
log.Fatal("Cache replication decode err: ", err)
}
rw.Lock()
for key, dbs := range replication {
database[key] = &DB{
Storage: dbs,
RW : &sync.RWMutex{},
}
}
rw.Unlock()
log.Println("Cache replication: Ok")
}
func replication(file string) {
encode := Replication{
"replication":map[string]interface{}{
"replication": "",
},
}
rw.RLock()
for k, v := range database {
encode[k] = v.Storage
}
rw.RUnlock()
json, _ := json.Marshal(encode)
saveFile(file, string(json))
}
func saveFile(file, raw string) {
f, err := os.Create(file)
if err != nil {
return
}
defer f.Close()
f.WriteString(raw)
}
Answer the question
In order to leave comments, you need to log in
What prevents declaring a structure as a json structure?
type Config struct {
Database struct {
DatabaseName string `json:"database_name"`
DatabasePassword string `json:"database_password"`
DatabaseUser string `json:"database_user"`
DatabasePort int `json:"database_port"`
} `json:"database"`
Accounts struct {
AutoCreate bool `json:"auto_create"`
} `json:"accounts"`
Client struct {
BanTimeForBruteForcing int `json:"ban_time_for_brute_forcing"`
Host string `json:"host"`
LoginTryBeforeBan int `json:"login_try_before_ban"`
Port int `json:"port"`
} `json:"client"`
Server struct {
Pingpong bool `json:"pingpong"`
Host string `json:"host"`
PingpongDelay bool `json:"pingpong_delay"`
PingpongDelayTime int `json:"pingpong_delay_time"`
Port int `json:"port"`
} `json:"server"`
}
If you need to transform complex structures according to some special logic, then it may make sense to use your own marshaling method. Here is a small rough example, but in general I think the idea can be conveyed correctly:
type Person struct {
Id int
Name string
}
func (p Person) MarshalJSON() ([]byte, error) {
// Your custom logic
return []byte(`{"name": "` + p.Name + `"}`), nil
}
func main() {
user := Person{Id: 1, Name: "Mr.Incognito"}
json.NewEncoder(os.Stdout).Encode(user)
// Вместо всей структуры выведет только {"name":"Mr.Incognito"}
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question