From fcd8bc838707cc43066fb0c986eb0ddb58f0c9b8 Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Mon, 2 Jul 2012 13:11:28 +0300 Subject: [PATCH] created marshal strategy --- timespans/actions.go | 9 +++-- timespans/actions_test.go | 14 ++++--- timespans/calldesc_test.go | 11 +++-- timespans/storage_interface.go | 73 ++++++++++++++++++++++++++++++++++ timespans/storage_redis.go | 51 ++++++++---------------- timespans/storage_redix.go | 43 ++++++++------------ 6 files changed, 127 insertions(+), 74 deletions(-) diff --git a/timespans/actions.go b/timespans/actions.go index bca147f57..d50941a52 100644 --- a/timespans/actions.go +++ b/timespans/actions.go @@ -196,14 +196,15 @@ func (at *ActionTiming) GetNextStartTime() (t time.Time) { return } } - + // weekdays if i.WeekDays != nil && len(i.WeekDays) > 0 { sort.Sort(i.WeekDays) if t.IsZero() { t = time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second(), 0, now.Location()) } - for _, j := range []int{0, 1, 2, 3, 4, 5, 6} { - t = time.Date(t.Year(), t.Month(), t.Day()+j, t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), t.Location()) + d := t.Day() + for _, j := range []int{0, 1, 2, 3, 4, 5, 6, 7} { + t = time.Date(t.Year(), t.Month(), d+j, t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), t.Location()) for _, wd := range i.WeekDays { if t.Weekday() == wd && (t.Equal(now) || t.After(now)) { return @@ -211,7 +212,7 @@ func (at *ActionTiming) GetNextStartTime() (t time.Time) { } } } - + // monthdays if i.MonthDays != nil && len(i.MonthDays) > 0 { sort.Sort(i.MonthDays) now := time.Now() diff --git a/timespans/actions_test.go b/timespans/actions_test.go index e90e3dbf6..d9f7eb2b9 100644 --- a/timespans/actions_test.go +++ b/timespans/actions_test.go @@ -50,9 +50,10 @@ func TestActionTimingOnlyWeekdays(t *testing.T) { y, m, d := now.Date() h, min, s := now.Clock() e := time.Date(y, m, d, h, min, s, 0, time.Local) - for _, i := range []int{0, 1, 2, 3, 4, 5, 6} { - e = time.Date(e.Year(), e.Month(), e.Day()+i, e.Hour(), e.Minute(), e.Second(), e.Nanosecond(), e.Location()) - if e.Weekday() == time.Monday { + day := e.Day() + for _, i := range []int{0, 1, 2, 3, 4, 5, 6, 7} { + e = time.Date(e.Year(), e.Month(), day+i, e.Hour(), e.Minute(), e.Second(), e.Nanosecond(), e.Location()) + if e.Weekday() == time.Monday && (e.Equal(now) || e.After(now)) { break } } @@ -67,9 +68,10 @@ func TestActionTimingHourWeekdays(t *testing.T) { now := time.Now() y, m, d := now.Date() e := time.Date(y, m, d, 10, 1, 0, 0, time.Local) - for _, i := range []int{0, 1, 2, 3, 4, 5, 6} { - e = time.Date(e.Year(), e.Month(), e.Day()+i, e.Hour(), e.Minute(), e.Second(), e.Nanosecond(), e.Location()) - if e.Weekday() == time.Monday { + day := e.Day() + for _, i := range []int{0, 1, 2, 3, 4, 5, 6, 7} { + e = time.Date(e.Year(), e.Month(), day+i, e.Hour(), e.Minute(), e.Second(), e.Nanosecond(), e.Location()) + if e.Weekday() == time.Monday && (e.Equal(now) || e.After(now)) { break } } diff --git a/timespans/calldesc_test.go b/timespans/calldesc_test.go index 403551cba..fb3f58495 100644 --- a/timespans/calldesc_test.go +++ b/timespans/calldesc_test.go @@ -128,11 +128,14 @@ func TestUniquePrice(t *testing.T) { } func TestPresentSecodCost(t *testing.T) { - t1 := time.Date(2012, time.February, 8, 22, 50, 0, 0, time.UTC) - t2 := time.Date(2012, time.February, 8, 23, 50, 21, 0, time.UTC) - cd := &CallDescriptor{Direction: "OUT", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0723", TimeStart: t1, TimeEnd: t2} + cd := &CallDescriptor{Direction: "OUT", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0723"} result, _ := cd.getPresentSecondCost() - expected := 0.5 + expected := 1.0 + now := time.Now() + after18 := time.Date(now.Year(), now.Month(), now.Day(), 18, 0, 0, 1, now.Location()) + if now.After(after18) { + expected = 0.5 + } if result != expected { t.Errorf("Expected %v was %v", expected, result) } diff --git a/timespans/storage_interface.go b/timespans/storage_interface.go index 2fd546da5..cc19d081d 100644 --- a/timespans/storage_interface.go +++ b/timespans/storage_interface.go @@ -18,6 +18,12 @@ along with this program. If not, see package timespans +import ( + "encoding/json" + "encoding/gob" + "bytes" +) + /* Interface for storage providers. */ @@ -36,3 +42,70 @@ type StorageGetter interface { SetActionTimings(string, []*ActionTiming) error GetAllActionTimings() ([]*ActionTiming, error) } + +type Marshaler interface { + Marshal(v interface{}) ([]byte, error) + Unmarshal(data []byte, v interface{}) error +} + +type MarshalStrategy struct { + marshaler Marshaler +} + +func (ms *MarshalStrategy) SetMarshaler(m Marshaler) { + ms.marshaler = m +} + +func (ms *MarshalStrategy) Marshal(v interface{}) ([]byte, error) { + return ms.marshaler.Marshal(v) +} + +func (ms *MarshalStrategy) Unmarshal(data []byte, v interface{}) error { + return ms.marshaler.Unmarshal(data, v) +} + +type JSONMarshaler struct{} + +func (jm *JSONMarshaler) Marshal(v interface{}) ([]byte, error) { + return json.Marshal(v) +} + +func (jm *JSONMarshaler) Unmarshal(data []byte, v interface{}) error { + return json.Unmarshal(data, v) +} + +type JSONBufMarshaler struct { + buf bytes.Buffer +} + +func (jbm *JSONBufMarshaler) Marshal(v interface{}) (data []byte, err error) { + jbm.buf.Reset() + if err = json.NewEncoder(&jbm.buf).Encode(v); err == nil { + data = jbm.buf.Bytes() + } + return +} + +func (jbm *JSONBufMarshaler) Unmarshal(data []byte, v interface{}) error { + jbm.buf.Reset() + jbm.buf.Write(data) + return json.NewDecoder(&jbm.buf).Decode(&v) +} + +type GOBMarshaler struct { + buf bytes.Buffer +} + +func (gm *GOBMarshaler) Marshal(v interface{}) (data []byte, err error) { + gm.buf.Reset() + if err = gob.NewEncoder(&gm.buf).Encode(v); err == nil { + data = gm.buf.Bytes() + } + return +} + +func (gm *GOBMarshaler) Unmarshal(data []byte, v interface{}) error { + gm.buf.Reset() + gm.buf.Write(data) + return gob.NewDecoder(&gm.buf).Decode(&v) +} diff --git a/timespans/storage_redis.go b/timespans/storage_redis.go index 4708362de..b86048af8 100644 --- a/timespans/storage_redis.go +++ b/timespans/storage_redis.go @@ -19,10 +19,6 @@ along with this program. If not, see package timespans import ( - // "bytes" - // "encoding/gob" - // "log" - "encoding/json" "github.com/simonz05/godis" ) @@ -33,12 +29,14 @@ const ( type RedisStorage struct { dbNb int db *godis.Client - //net bytes.Buffer + ms *MarshalStrategy } func NewRedisStorage(address string, db int) (*RedisStorage, error) { ndb := godis.New(address, db, "") - return &RedisStorage{db: ndb, dbNb: db}, nil + ms := &MarshalStrategy{} + ms.SetMarshaler(&JSONMarshaler{}) + return &RedisStorage{db: ndb, dbNb: db, ms: ms}, nil } func (rs *RedisStorage) Close() { @@ -50,88 +48,73 @@ func (rs *RedisStorage) Flush() error { } func (rs *RedisStorage) GetActivationPeriodsOrFallback(key string) (aps []*ActivationPeriod, fallbackKey string, err error) { - //rs.db.Select(rs.dbNb) elem, err := rs.db.Get(key) if err != nil { return } - // rs.net.Reset() - // rs.net.Write(elem) - // err = gob.NewDecoder(&rs.net).Decode(&aps) - err = json.Unmarshal(elem, &aps) + err = rs.ms.Unmarshal(elem, &aps) if err != nil { - // err = gob.NewDecoder(&rs.net).Decode(&fallbackKey) - err = json.Unmarshal(elem, &fallbackKey) + err = rs.ms.Unmarshal(elem, &fallbackKey) } return } func (rs *RedisStorage) SetActivationPeriodsOrFallback(key string, aps []*ActivationPeriod, fallbackKey string) (err error) { - //.db.Select(rs.dbNb) var result []byte - //rs.net.Reset() if len(aps) > 0 { - //gob.NewEncoder(&rs.net).Encode(aps) - result, err = json.Marshal(aps) + result, err = rs.ms.Marshal(aps) } else { - //gob.NewEncoder(&rs.net).Encode(fallbackKey) - result, err = json.Marshal(fallbackKey) + result, err = rs.ms.Marshal(fallbackKey) } - //result = rs.net.Bytes() return rs.db.Set(key, result) } func (rs *RedisStorage) GetDestination(key string) (dest *Destination, err error) { - //rs.db.Select(rs.dbNb + 1) if values, err := rs.db.Get(key); err == nil { dest = &Destination{Id: key} - err = json.Unmarshal(values, dest) + err = rs.ms.Unmarshal(values, dest) } return } func (rs *RedisStorage) SetDestination(dest *Destination) (err error) { - //rs.db.Select(rs.dbNb + 1) - result, err := json.Marshal(dest) + result, err := rs.ms.Marshal(dest) return rs.db.Set(dest.Id, result) } func (rs *RedisStorage) GetActions(key string) (as []*Action, err error) { if values, err := rs.db.Get(key); err == nil { - err = json.Unmarshal(values, &as) + err = rs.ms.Unmarshal(values, &as) } return } func (rs *RedisStorage) SetActions(key string, as []*Action) (err error) { - //rs.db.Select(rs.dbNb + 2) - result, err := json.Marshal(as) + result, err := rs.ms.Marshal(as) return rs.db.Set(key, result) } func (rs *RedisStorage) GetUserBalance(key string) (ub *UserBalance, err error) { - //rs.db.Select(rs.dbNb + 3) if values, err := rs.db.Get(key); err == nil { ub = &UserBalance{Id: key} - err = json.Unmarshal(values, ub) + err = rs.ms.Unmarshal(values, ub) } return } func (rs *RedisStorage) SetUserBalance(ub *UserBalance) (err error) { - //rs.db.Select(rs.dbNb + 3) - result, err := json.Marshal(ub) + result, err := rs.ms.Marshal(ub) return rs.db.Set(ub.Id, result) } func (rs *RedisStorage) GetActionTimings(key string) (ats []*ActionTiming, err error) { if values, err := rs.db.Get(key); err == nil { - err = json.Unmarshal(values, &ats) + err = rs.ms.Unmarshal(values, &ats) } return } func (rs *RedisStorage) SetActionTimings(key string, ats []*ActionTiming) (err error) { - result, err := json.Marshal(ats) + result, err := rs.ms.Marshal(ats) return rs.db.Set(key, result) } @@ -146,7 +129,7 @@ func (rs *RedisStorage) GetAllActionTimings() (ats []*ActionTiming, err error) { } for _, v := range values.BytesArray() { var tempAts []*ActionTiming - err = json.Unmarshal(v, &tempAts) + err = rs.ms.Unmarshal(v, &tempAts) ats = append(ats, tempAts...) } return diff --git a/timespans/storage_redix.go b/timespans/storage_redix.go index fbd4f2470..e1f3a0f5a 100644 --- a/timespans/storage_redix.go +++ b/timespans/storage_redix.go @@ -20,15 +20,12 @@ package timespans import ( "github.com/fzzbt/radix/redis" - "encoding/json" - // "encoding/gob" - // "bytes" "log" ) type RedixStorage struct { db *redis.Client - //net bytes.Buffer + ms *MarshalStrategy } func NewRedixStorage(address string, db int) (*RedixStorage, error) { @@ -36,7 +33,9 @@ func NewRedixStorage(address string, db int) (*RedixStorage, error) { if err != nil { log.Fatalf("Could not connect to redis server: %v", err) } - return &RedixStorage{db: ndb}, nil + ms := &MarshalStrategy{} + ms.SetMarshaler(&JSONMarshaler{}) + return &RedixStorage{db: ndb, ms: ms}, nil } func (rs *RedixStorage) Close() { @@ -53,77 +52,69 @@ func (rs *RedixStorage) GetActivationPeriodsOrFallback(key string) (aps []*Activ if err != nil { return } - //rs.net.Reset() - //rs.net.Write(elem) - //err = gob.NewDecoder(&rs.net).Decode(&aps) - err = json.Unmarshal(elem, &aps) + err = rs.ms.Unmarshal(elem, &aps) if err != nil { - //err = gob.NewDecoder(&rs.net).Decode(&fallbackKey) - err = json.Unmarshal(elem, &fallbackKey) + err = rs.ms.Unmarshal(elem, &fallbackKey) } return } func (rs *RedixStorage) SetActivationPeriodsOrFallback(key string, aps []*ActivationPeriod, fallbackKey string) (err error) { var result []byte - //rs.net.Reset() if len(aps) > 0 { - //gob.NewEncoder(&rs.net).Encode(aps) - result, err = json.Marshal(&aps) + result, err = rs.ms.Marshal(&aps) } else { - //gob.NewEncoder(&rs.net).Encode(fallbackKey) - result, err = json.Marshal(fallbackKey) + result, err = rs.ms.Marshal(fallbackKey) } - //result = rs.net.Bytes() return rs.db.Set(key, result).Err } func (rs *RedixStorage) GetDestination(key string) (dest *Destination, err error) { if values, err := rs.db.Get(key).Bytes(); err == nil { dest = &Destination{Id: key} - err = json.Unmarshal(values, dest) + err = rs.ms.Unmarshal(values, dest) } return } func (rs *RedixStorage) SetDestination(dest *Destination) (err error) { - result, err := json.Marshal(dest) + result, err := rs.ms.Marshal(dest) return rs.db.Set(dest.Id, result).Err } func (rs *RedixStorage) GetActions(key string) (as []*Action, err error) { if values, err := rs.db.Get(key).Bytes(); err == nil { - err = json.Unmarshal(values, &as) + err = rs.ms.Unmarshal(values, &as) } return } func (rs *RedixStorage) SetActions(key string, as []*Action) (err error) { - result, err := json.Marshal(as) + result, err := rs.ms.Marshal(as) return rs.db.Set(key, result).Err } func (rs *RedixStorage) GetUserBalance(key string) (ub *UserBalance, err error) { if values, err := rs.db.Get(key).Bytes(); err == nil { ub = &UserBalance{Id: key} - err = json.Unmarshal(values, ub) + err = rs.ms.Unmarshal(values, ub) } return } func (rs *RedixStorage) SetUserBalance(ub *UserBalance) (err error) { - result, err := json.Marshal(ub) + result, err := rs.ms.Marshal(ub) return rs.db.Set(ub.Id, result).Err } func (rs *RedixStorage) GetActionTimings(key string) (ats []*ActionTiming, err error) { if values, err := rs.db.Get(key).Bytes(); err == nil { - err = json.Unmarshal(values, ats) + err = rs.ms.Unmarshal(values, ats) } return } func (rs *RedixStorage) SetActionTimings(key string, ats []*ActionTiming) (err error) { - result, err := json.Marshal(ats) + result, err := rs.ms.Marshal(ats) return rs.db.Set(key, result).Err } @@ -138,7 +129,7 @@ func (rs *RedixStorage) GetAllActionTimings() (ats []*ActionTiming, err error) { } for _, v := range values { var tempAts []*ActionTiming - err = json.Unmarshal([]byte(v), &ats) + err = rs.ms.Unmarshal([]byte(v), &ats) ats = append(ats, tempAts...) } return