Make freezer a little more independant of JSON.

This commit is contained in:
Mikkel Krautz 2011-04-08 13:50:21 +02:00
parent 3ae9881d91
commit 3570847876
2 changed files with 89 additions and 69 deletions

View file

@ -63,8 +63,13 @@ func MurmurImport(filename string) (err os.Error) {
zf, err := zlib.NewWriterLevel(f, zlib.BestCompression) zf, err := zlib.NewWriterLevel(f, zlib.BestCompression)
fz, err := m.Freeze()
if err != nil {
log.Fatalf("Unable to freeze server: %s", err.String())
}
enc := json.NewEncoder(zf) enc := json.NewEncoder(zf)
err = enc.Encode(m) err = enc.Encode(fz)
if err != nil { if err != nil {
log.Printf("%s", err.String()) log.Printf("%s", err.String())
return return
@ -149,7 +154,7 @@ func main() {
servers := make(map[int64]*Server) servers := make(map[int64]*Server)
for _, name := range names { for _, name := range names {
log.Printf("Loading server %v", name) log.Printf("Loading server %v", name)
s, err := NewServerFromGrumbleDesc(filepath.Join(*datadir, name)) s, err := NewServerFromFrozen(filepath.Join(*datadir, name))
if err != nil { if err != nil {
log.Fatalf("Unable to load server: %s", err.String()) log.Fatalf("Unable to load server: %s", err.String())
} }

131
json.go
View file

@ -6,25 +6,26 @@ import (
"compress/zlib" "compress/zlib"
) )
type jsonServer struct { type frozenServer struct {
Id int "id" Id int "id"
MaxUsers int "max_user" MaxUsers int "max_user"
Channels []jsonChannel "channels" Channels []frozenChannel "channels"
} }
type jsonChannel struct { type frozenChannel struct {
Id int "id" Id int "id"
Name string "name" Name string "name"
ParentId int "parent_id" ParentId int "parent_id"
Position int64 "position" Position int64 "position"
InheritACL bool "inherit_acl" InheritACL bool "inherit_acl"
ACL []jsonACL "acl" Links []int "links"
Groups []jsonGroup "groups" ACL []frozenACL "acl"
Groups []frozenGroup "groups"
Description string "description" Description string "description"
DescriptionHash []byte "description_hash" DescriptionHash []byte "description_hash"
} }
type jsonACL struct { type frozenACL struct {
UserId int "user_id" UserId int "user_id"
Group string "group" Group string "group"
ApplyHere bool "apply_here" ApplyHere bool "apply_here"
@ -33,7 +34,7 @@ type jsonACL struct {
Deny uint32 "deny" Deny uint32 "deny"
} }
type jsonGroup struct { type frozenGroup struct {
Name string "name" Name string "name"
Inherit bool "inherit" Inherit bool "inherit"
Inheritable bool "inheritable" Inheritable bool "inheritable"
@ -41,78 +42,92 @@ type jsonGroup struct {
Remove []int "remove" Remove []int "remove"
} }
// Marshal a server into a JSON object // Freeze a server
func (server *Server) MarshalJSON() (buf []byte, err os.Error) { func (server *Server) Freeze() (fs frozenServer, err os.Error) {
obj := make(map[string]interface{}) fs.Id = int(server.Id)
obj["id"] = server.Id fs.MaxUsers = server.MaxUsers
obj["max_user"] = server.MaxUsers
channels := []interface{}{} channels := []frozenChannel{}
for _, c := range server.Channels { for _, c := range server.Channels {
channels = append(channels, c) fc, err := c.Freeze()
if err != nil {
return
} }
obj["channels"] = channels channels = append(channels, fc)
}
fs.Channels = channels
return json.Marshal(obj) return
} }
// Marshal a Channel into a JSON object // Freeze a channel
func (channel *Channel) MarshalJSON() (buf []byte, err os.Error) { func (channel *Channel) Freeze() (fc frozenChannel, err os.Error) {
obj := make(map[string]interface{}) fc.Id = channel.Id
fc.Name = channel.Name
obj["id"] = channel.Id
obj["name"] = channel.Name
if channel.parent != nil { if channel.parent != nil {
obj["parent_id"] = channel.parent.Id fc.ParentId = channel.parent.Id
} else { } else {
obj["parent_id"] = -1 fc.ParentId = -1
} }
fc.Position = int64(channel.Position)
fc.InheritACL = channel.InheritACL
fc.Description = channel.Description
fc.DescriptionHash = channel.DescriptionHash
obj["position"] = channel.Position acls := []frozenACL{}
obj["inherit_acl"] = channel.InheritACL for _, acl := range channel.ACL {
obj["description"] = channel.Description facl, err := acl.Freeze()
obj["description_hash"] = channel.DescriptionHash if err != nil {
return
}
acls = append(acls, facl)
}
fc.ACL = acls
obj["acl"] = channel.ACL groups := []frozenGroup{}
groups := []*Group{}
for _, grp := range channel.Groups { for _, grp := range channel.Groups {
groups = append(groups, grp) fgrp, err := grp.Freeze()
if err != nil {
return
} }
obj["groups"] = groups groups = append(groups, fgrp)
}
fc.Groups = groups
links := []int{} links := []int{}
for cid, _ := range channel.Links { for cid, _ := range channel.Links {
links = append(links, cid) links = append(links, cid)
} }
fc.Links = links
return json.Marshal(obj) return
} }
func (acl *ChannelACL) MarshalJSON() (buf []byte, err os.Error) { // Freeze a ChannelACL
obj := make(map[string]interface{}) func (acl *ChannelACL) Freeze() (facl frozenACL, err os.Error) {
obj["user_id"] = acl.UserId facl.UserId = acl.UserId
obj["group"] = acl.Group facl.Group = acl.Group
obj["apply_here"] = acl.ApplyHere facl.ApplyHere = acl.ApplyHere
obj["apply_subs"] = acl.ApplySubs facl.ApplySubs = acl.ApplySubs
obj["allow"] = acl.Allow facl.Allow = uint32(acl.Allow)
obj["deny"] = acl.Deny facl.Deny = uint32(acl.Deny)
return json.Marshal(obj) return
} }
func (group *Group) MarshalJSON() (buf []byte, err os.Error) { // Freeze a Group
obj := make(map[string]interface{}) func (group *Group) Freeze() (fgrp frozenGroup, err os.Error) {
obj["name"] = group.Name fgrp.Name = group.Name
obj["inherit"] = group.Inherit fgrp.Inherit = group.Inherit
obj["inheritable"] = group.Inheritable fgrp.Inheritable = group.Inheritable
obj["add"] = group.AddUsers() fgrp.Add = group.AddUsers()
obj["remove"] = group.RemoveUsers() fgrp.Remove = group.RemoveUsers()
return json.Marshal(obj) return
} }
// Create a new Server from a Grumble zlib-compressed JSON description // Create a new Server from a frozen server
func NewServerFromGrumbleDesc(filename string) (s *Server, err os.Error) { func NewServerFromFrozen(filename string) (s *Server, err os.Error) {
descFile, err := os.Open(filename) descFile, err := os.Open(filename)
if err != nil { if err != nil {
return nil, err return nil, err
@ -124,18 +139,18 @@ func NewServerFromGrumbleDesc(filename string) (s *Server, err os.Error) {
return nil, err return nil, err
} }
srv := new(jsonServer) fs := new(frozenServer)
decoder := json.NewDecoder(zr) decoder := json.NewDecoder(zr)
decoder.Decode(&srv) decoder.Decode(&fs)
s, err = NewServer(int64(srv.Id), "", int(DefaultPort+srv.Id-1)) s, err = NewServer(int64(fs.Id), "", int(DefaultPort+fs.Id-1))
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Add all channels, but don't hook up parent/child relationships // Add all channels, but don't hook up parent/child relationships
// until all of them are loaded. // until all of them are loaded.
for _, jc := range srv.Channels { for _, jc := range fs.Channels {
c := NewChannel(jc.Id, jc.Name) c := NewChannel(jc.Id, jc.Name)
c.Position = int(jc.Position) c.Position = int(jc.Position)
c.InheritACL = jc.InheritACL c.InheritACL = jc.InheritACL
@ -169,7 +184,7 @@ func NewServerFromGrumbleDesc(filename string) (s *Server, err os.Error) {
} }
// Hook up children with their parents. // Hook up children with their parents.
for _, jc := range srv.Channels { for _, jc := range fs.Channels {
if jc.Id == 0 { if jc.Id == 0 {
continue continue
} }