// LoadStringEntities executes a SELECT query and returns a slice containing columns names and its string values func LoadStringEntities(db *sql.DB, dbSelect *dbr.SelectBuilder, query ...string) ([]StringEntities, error) { qry := strings.Join(query, " ") var args []interface{} if qry == "" && dbSelect != nil { qry, args = dbSelect.ToSql() } rows, err := db.Query(qry, args...) if err != nil { return nil, log.Error("codegen.LoadStringEntities.Query420", "err", err) } defer rows.Close() columnNames, err := rows.Columns() if err != nil { return nil, log.Error("codegen.LoadStringEntities.Columns", "err", err) } ret := make([]StringEntities, 0, 2000) rss := newRowTransformer(columnNames) for rows.Next() { if err := rows.Scan(rss.cp...); err != nil { return nil, log.Error("codegen.LoadStringEntities.Scan", "err", err) } err := rss.toString() if err != nil { return nil, log.Error("codegen.LoadStringEntities.ToString", "err", err) } rss.append(&ret) } return ret, nil }
// GetColumns returns all columns from a table. It discards the column // entity_type_id from some entity tables. The column attribute_model will also // be dropped from table eav_attribute func GetColumns(db *sql.DB, table string) (Columns, error) { var cols = make(Columns, 0, 200) rows, err := db.Query("SHOW COLUMNS FROM `" + table + "`") if err != nil { return nil, log.Error("codegen.GetColumns.Query", "err", err) } defer rows.Close() col := column{} for rows.Next() { err := rows.Scan(&col.Field, &col.Type, &col.Null, &col.Key, &col.Default, &col.Extra) if err != nil { return nil, log.Error("codegen.GetColumns.Scan", "err", err) } if isIgnoredColumn(table, col.Field.String) { continue } cols = append(cols, col) } err = rows.Err() if err != nil { return nil, log.Error("codegen.GetColumns.rows", "err", err) } return cols, nil }
// GetColumns returns all columns from a table. It discards the column entity_type_id from some // entity tables. func GetColumns(dbrSess dbr.SessionRunner, table string) (Columns, error) { var cols = make(Columns, 0, 100) sel := dbrSess.SelectBySql("SHOW COLUMNS FROM " + dbr.Quoter.Table(table)) selSql, selArg := sel.ToSql() rows, err := sel.Query(selSql, selArg...) if err != nil { return nil, log.Error("csdb.GetColumns.Query", "err", err, "query", selSql, "args", selArg) } defer rows.Close() col := Column{} for rows.Next() { err := rows.Scan(&col.Field, &col.Type, &col.Null, &col.Key, &col.Default, &col.Extra) if err != nil { return nil, log.Error("csdb.GetColumns.Rows.Scan", "err", err, "query", selSql, "args", selArg) } cols = append(cols, col) } err = rows.Err() if err != nil { return nil, log.Error("csdb.GetColumns.Rows.Err", "err", err, "query", selSql, "args", selArg) } return cols, nil }
// SetMandrill sets the Mandrill API for sending emails. This function is not // recursive and returns nil. @todo func SetMandrill(opts ...MandrillOptions) DaemonOption { return func(da *Daemon) DaemonOption { // this whole func is just a quick write down. no idea if it's working // and refactor ... 8-) apiKey := da.Config.GetString(config.ScopeStore(da.ScopeID), config.Path(PathSmtpMandrillAPIKey)) if apiKey == "" { da.lastErrs = append(da.lastErrs, errors.New("Mandrill API Key is empty.")) return nil } md, err := gochimp.NewMandrill(apiKey) if err != nil { da.lastErrs = append(da.lastErrs, err) return nil } for _, o := range opts { o(md) } da.sendFunc = func(from string, to []string, msg io.WriterTo) error { // @todo figure out if "to" contains To, CC and BCC addresses. addr, err := mail.ParseAddress(from) if err != nil { return log.Error("mail.daemon.Mandrill.ParseAddress", "err", err, "from", from, "to", to) } r := gochimp.Recipient{ Name: addr.Name, Email: addr.Address, } var buf bytes.Buffer if _, err := msg.WriteTo(&buf); err != nil { return log.Error("mail.daemon.Mandrill.MessageWriteTo", "err", err, "from", from, "to", to, "msg", buf.String()) } resp, err := md.MessageSendRaw(buf.String(), to, r, false) if err != nil { return log.Error("mail.daemon.Mandrill.MessageSendRaw", "err", err, "from", from, "to", to, "msg", buf.String()) } if log.IsDebug() { log.Debug("mail.daemon.Mandrill.MessageSendRaw", "resp", resp, "from", from, "to", to, "msg", buf.String()) } // The last arg in MessageSendRaw means async in the Mandrill API: // Async: enable a background sending mode that is optimized for bulk sending. // In async mode, messages/send will immediately return a status of "queued" // for every recipient. To handle rejections when sending in async mode, set // up a webhook for the 'reject' event. Defaults to false for messages with // no more than 10 recipients; messages with more than 10 recipients are // always sent asynchronously, regardless of the value of async. return nil } da.dialer = nil return nil } }
func sendMsgRecoverable(id int, sl MessageReceiver, a arg) (err error) { defer func() { // protect ... you'll never know if r := recover(); r != nil { if recErr, ok := r.(error); ok { err = log.Error("config.pubSub.publish.recover.err", "err", recErr) } else { err = log.Error("config.pubSub.publish.recover.r", "recover", r) } // the overall trick here is, that defer will assign a new error to err // and therefore will overwrite the returned nil value! } }() err = sl.MessageConfig(a.path, a.scope, a.scopeID) return }
// RESTStores creates a list of all stores func RESTStores(sm *Manager) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { stores, err := sm.Stores() if err != nil { log.Error("store.RESTStores.Stores", "err", err, "req", r) http.Error(w, err.Error(), http.StatusInternalServerError) } err = net.WriteJSON(w, stores) if err != nil { log.Error("store.RESTStores.WriteJSON", "err", err, "req", r) http.Error(w, err.Error(), http.StatusInternalServerError) } } }
// Write puts a value back into the manager. Example usage: // Default Scope: Write(config.Path("currency", "option", "base"), config.Value("USD")) // Website Scope: Write(config.Path("currency", "option", "base"), config.Value("EUR"), config.ScopeWebsite(w)) // Store Scope: Write(config.Path("currency", "option", "base"), config.ValueReader(resp.Body), config.ScopeStore(s)) func (m *Manager) Write(o ...ArgFunc) error { a, err := newArg(o...) if err != nil { return log.Error("config.Manager.Write.newArg", "err", err) } if a.isBubbling() { if log.IsDebug() { log.Debug("config.Manager.Write.isBubbling", "path", a.scopePathDefault(), "bubble", a.isBubbling(), "val", a.v) } m.v.Set(a.scopePathDefault(), a.v) aDefault := a aDefault.sg = ScopeDefaultID aDefault.si = ScopeID(0) m.sendMsg(aDefault) } if log.IsDebug() { log.Debug("config.Manager.Write", "path", a.scopePath(), "val", a.v) } a.scopeID() m.v.Set(a.scopePath(), a.v) m.sendMsg(a) return nil }
// ToJSON returns a JSON string, convenience function. func (s Slice) ToJSON() (string, error) { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(s); err != nil { return "", log.Error("config.ValueLabelSlice.ToJSON.Encode", "err", err, "slice", s) } return buf.String(), nil }
// DefaultSwedish sets the global and New() defaults swedish rounding. Errors will be logged. // http://en.wikipedia.org/wiki/Swedish_rounding func DefaultSwedish(i Interval) { if i < interval999 { gSwedish = i } else { log.Error("money.DefaultSwedish", "err", errors.New("Interval out of scope"), "interval", i) } }
func TestNull(t *testing.T) { log.SetNull() log.SetLevel(-1000) if log.IsTrace() { t.Error("There should be no trace") } if log.IsDebug() { t.Error("There should be no debug") } if log.IsInfo() { t.Error("There should be no info") } if log.IsWarn() { t.Error("There should be no warn") } var args []interface{} args = append(args, "key1", 1, "key2", 3.14152) log.Trace("Hello World", args...) log.Debug("Hello World", args...) log.Info("Hello World", args...) log.Warn("Hello World", args...) log.Error("Hello World", args...) log.Log(1, "Hello World", args) }
// Authorization represent a middleware handler for a http router. // For POST or PUT requests, it also parses the request body as a form. The // claims of a token will be appended to the requests Form map. So you // can access the token in any http/routing library. func (a *AuthManager) Authorization(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { token, err := jwt.ParseFromRequest(r, a.keyFunc) var inBL bool if token != nil { inBL = a.Blacklist.Has(token.Raw) } if token != nil && err == nil && token.Valid && !inBL { if err := appendTokenToForm(r, token, a.PostFormVarPrefix); err != nil { a.HTTPErrorHandler( log.Error("userjwt.AuthManager.Authenticate.appendTokenToForm", "err", err, "r", r, "token", token), ).ServeHTTP(w, r) } else { next.ServeHTTP(w, r) } } else { if log.IsInfo() { log.Info("userjwt.AuthManager.Authenticate", "err", err, "token", token, "blacklist", inBL) } a.HTTPErrorHandler(err).ServeHTTP(w, r) // is that really thread safe or other bug? } }) }
// Validate checks for duplicated configuration paths in all three hierarchy levels. func (ss SectionSlice) Validate() error { if len(ss) == 0 { return errgo.New("SectionSlice is empty") } // @todo try to pick the right strategy between maps and slice depending on the overall size of a full SectionSlice var pc = make(utils.StringSlice, ss.TotalFields()) // pc path checker i := 0 for _, s := range ss { for _, g := range s.Groups { for _, f := range g.Fields { arg, err := newArg(Path(s.ID, g.ID, f.ID)) if err != nil { log.Error("config.SectionSlice.Validate.newArg", "err", err, "s", s, "g", g, "f", f) } p := arg.scopePath() if pc.Include(p) { return errgo.Newf("Duplicate entry for path %s :: %s", p, ss.ToJSON()) } pc[i] = p i++ } } } return nil }
// GetEavValueTables returns a map of all custom and default EAV value tables for entity type codes. // Despite value_table_prefix can have in Magento a different table name we treat it here // as the table name itself. Not thread safe. func GetEavValueTables(dbrConn *dbr.Connection, entityTypeCodes []string) (TypeCodeValueTable, error) { typeCodeTables := make(TypeCodeValueTable, len(entityTypeCodes)) for _, typeCode := range entityTypeCodes { vtp, err := dbrConn.NewSession(). Select("`value_table_prefix`"). From(TablePrefix+TableEavEntityType). Where("`value_table_prefix` IS NOT NULL"). Where("`entity_type_code` = ?", typeCode). ReturnString() if err != nil && err != dbr.ErrNotFound { return nil, log.Error("codegen.GetEavValueTables.select", "err", err) } if vtp == "" { vtp = typeCode + TableNameSeparator + TableEntityTypeSuffix + TableNameSeparator // e.g. catalog_product_entity_ } else { vtp = vtp + TableNameSeparator } tableNames, err := GetTables(dbrConn.NewSession(), vtp+`%`) if err != nil { return nil, log.Error("codegen.GetEavValueTables.GetTables", "err", err) } if _, ok := typeCodeTables[typeCode]; !ok { typeCodeTables[typeCode] = make(map[string]string, len(tableNames)) } for _, t := range tableNames { valueSuffix := t[len(vtp):] if TableEntityTypeValueSuffixes.contains(valueSuffix) { /* other tables like catalog_product_entity_gallery, catalog_product_entity_group_price, catalog_product_entity_tier_price, etc are the backend model tables for different storage systems. they are not part of the default EAV model. */ typeCodeTables[typeCode][t] = valueSuffix } } } return typeCodeTables, nil }
// ToJSON transforms the whole slice into JSON func (gs GroupSlice) ToJSON() string { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(gs); err != nil { log.Error("config.GroupSlice.ToJSON.Encode", "err", err) return "" } return buf.String() }
// ToJSON returns a JSON string func (s ValueLabelSlice) ToJSON() string { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(s); err != nil { log.Error("ValueLabelSlice=ToJSON", "err", err) return "" } return buf.String() }
// GetDateTime returns a date and time object from the manager. Example usage see GetString. func (m *Manager) GetDateTime(o ...ArgFunc) time.Time { vs := m.get(o...) t, err := cast.ToTimeE(vs) if err != nil { log.Error("config.Manager.GetDateTime.ToTimeE", "err", err, "val", vs) } return t }
// mustNewArg panics on error. useful for initialization process func mustNewArg(opts ...ArgFunc) arg { a, err := newArg(opts...) if err != nil { log.Error("config.mustNewArg", "err", err) panic(err) } return a }
// IsSet checks if a key is in the config. Does not bubble. Returns false on error. func (m *Manager) IsSet(o ...ArgFunc) bool { a, err := newArg(o...) if err != nil { log.Error("config.Manager.IsSet.newArg", "err", err) return false } return m.v.IsSet(a.scopePath()) }
// NewSourceCurrencyAll creates a new option for all currencies. If one argument of // the ModelConstructor has been provided you may skip the calling of Construct(). func NewSourceCurrencyAll(mc ...config.ModelConstructor) *SourceCurrencyAll { sca := &SourceCurrencyAll{} if len(mc) == 1 { if err := sca.Construct(mc[0]); err != nil { log.Error("directory.NewSourceCurrencyAll.Construct", "err", err) } } return sca }
func sendMessages(subs map[int]MessageReceiver, a arg) (evict []int) { for id, s := range subs { if err := sendMsgRecoverable(id, s, a); err != nil { log.Error("config.pubSub.publish.sendMessages", "err", err, "id", id) evict = append(evict, id) // mark Subscribers for removal which failed ... } } return }
// Append adds a table. Overrides silently existing entries. func (tm *TableManager) Append(i Index, ts *Table) error { if ts == nil { return log.Error("csdb.TableManager.Init", "err", errgo.Newf("Table pointer cannot be nil for Index %d", i)) } tm.mu.Lock() tm.ts[i] = ts tm.mu.Unlock() // use defer once there are multiple returns return nil }
// FmtNumber formats a number according to the currency format. Internal rounding // will be applied. Returns the number bytes written or an error. Thread safe. // For more details please see the interface documentation. func (c *Currency) FmtNumber(w io.Writer, sign int, intgr int64, prec int, frac int64) (int, error) { c.mu.Lock() defer c.mu.Unlock() c.clearBuf() if _, err := c.Number.FmtNumber(&c.buf, sign, intgr, prec, frac); err != nil { return 0, log.Error("i18n.Currency.FmtNumber.FmtNumber", "err", err, "buffer", string(c.buf), "sign", sign, "i", intgr, "prec", prec, "frac", frac) } return c.flushBuf(w) }
// FmtCurrencyFloat64 formats a float value, does internal maybe incorrect rounding. // Returns the number bytes written or an error. Thread safe. func (c *Currency) FmtFloat64(w io.Writer, f float64) (int, error) { c.mu.Lock() defer c.mu.Unlock() c.clearBuf() if _, err := c.Number.FmtFloat64(&c.buf, f); err != nil { return 0, log.Error("i18n.Currency.FmtFloat64.FmtFloat64", "err", err, "buffer", string(c.buf), "float64", f) } return c.flushBuf(w) }
func (dm *Daemon) workerDial() error { var s gomail.SendCloser var err error open := false for { select { case m, ok := <-dm.msgChan: if !ok { dm.closed = true return nil } if !open { if s, err = dm.dialer.Dial(); err != nil { return log.Error("mail.daemon.workerDial.Dial", "err", err, "message", m) } open = true } if err := gomail.Send(s, m); err != nil { log.Error("mail.daemon.workerDial.Send", "err", err, "message", m) } // Close the connection to the SMTP server if no email was sent in // the last n seconds. case <-time.After(dm.SmtpTimeout): // if open && dm.lastIDchanged { // // once the configuration changed and there is an open connection // // we have to close it and reconnect with the new SMTP login data. // if err := s.Close(); err != nil { // log.Error("mail.daemon.workerDial.lastIDchanged.Close", "err", err) // no need to return // } // open = false // // init new dialer // dm.dialer = dialerPool.allocate(dm) // } if open { if err := s.Close(); err != nil { return log.Error("mail.daemon.workerDial.timeout.Close", "err", err) } open = false } } } }
// String for money type representation in a specific locale. func (c Currency) String() string { var bufC buf if _, err := c.LocalizeWriter(&bufC); err != nil { if log.IsTrace() { log.Trace("Currency=String", "err", err, "c", c) } log.Error("Currency=String", "err", err, "c", c) } return string(bufC) }
// ID with which you can identify a daemon connection to the same SMTP server // independent of the scope ID. func (dm *Daemon) ID() uint64 { var h hash.Hash64 h = fnv.New64() data := []byte(dm.getHost() + strconv.Itoa(dm.getPort()) + dm.getUsername()) if _, err := h.Write(data); err != nil { log.Error("mail.daemon.ID", "err", err, "hashWrite", string(data)) return 0 } return h.Sum64() }
func offlineSend(from string, to []string, msg io.WriterTo) error { if OfflineLogger.IsInfo() { var buf bytes.Buffer if _, err := msg.WriteTo(&buf); err != nil { return log.Error("mail.daemon.OfflineSend", "err", err, "buf", buf.String(), "message", msg) } OfflineLogger.Info("mail.Send", "from", from, "to", to, "msg", buf.String()) } return nil }
func defaultAdapterErrFunc(rw http.ResponseWriter, req *http.Request, err error) { if log.IsDebug() { log.Error("ctxhttp.AdapterErrorFunc", "err", err, "req", req, "url", req.URL) } code := http.StatusBadRequest http.Error(rw, fmt.Sprintf( "%s\nApp Error: %s", http.StatusText(code), err, ), code) }
// Swedish sets the Swedish rounding // http://en.wikipedia.org/wiki/Swedish_rounding // Errors will be logged func Swedish(i Interval) OptionFunc { if i >= interval999 { log.Error("Currency=SetSwedishRounding", "err", errors.New("Interval out of scope. Resetting."), "interval", i) i = Interval000 } return func(c *Currency) OptionFunc { previous := c.Interval c.Interval = i return Swedish(previous) } }
// get generic getter ... not sure if this should be public ... func (m *Manager) get(o ...ArgFunc) interface{} { a, err := newArg(o...) if err != nil { return log.Error("config.Manager.get.newArg", "err", err) } vs := m.v.Get(a.scopePath()) // vs = value scope if vs == nil && a.isBubbling() { vs = m.v.Get(a.scopePathDefault()) } return vs }