This commit is contained in:
Shlomi Noach 2016-10-14 14:21:08 +02:00
Родитель 2766c87cee
Коммит 0983ca9310
11 изменённых файлов: 1225 добавлений и 0 удалений

2
vendor/github.com/codegangsta/inject/.gitignore сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,2 @@
inject
inject.test

20
vendor/github.com/codegangsta/inject/LICENSE сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2013 Jeremy Saenz
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

92
vendor/github.com/codegangsta/inject/README.md сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,92 @@
# inject
--
import "github.com/codegangsta/inject"
Package inject provides utilities for mapping and injecting dependencies in
various ways.
Language Translations:
* [简体中文](translations/README_zh_cn.md)
## Usage
#### func InterfaceOf
```go
func InterfaceOf(value interface{}) reflect.Type
```
InterfaceOf dereferences a pointer to an Interface type. It panics if value is
not an pointer to an interface.
#### type Applicator
```go
type Applicator interface {
// Maps dependencies in the Type map to each field in the struct
// that is tagged with 'inject'. Returns an error if the injection
// fails.
Apply(interface{}) error
}
```
Applicator represents an interface for mapping dependencies to a struct.
#### type Injector
```go
type Injector interface {
Applicator
Invoker
TypeMapper
// SetParent sets the parent of the injector. If the injector cannot find a
// dependency in its Type map it will check its parent before returning an
// error.
SetParent(Injector)
}
```
Injector represents an interface for mapping and injecting dependencies into
structs and function arguments.
#### func New
```go
func New() Injector
```
New returns a new Injector.
#### type Invoker
```go
type Invoker interface {
// Invoke attempts to call the interface{} provided as a function,
// providing dependencies for function arguments based on Type. Returns
// a slice of reflect.Value representing the returned values of the function.
// Returns an error if the injection fails.
Invoke(interface{}) ([]reflect.Value, error)
}
```
Invoker represents an interface for calling functions via reflection.
#### type TypeMapper
```go
type TypeMapper interface {
// Maps the interface{} value based on its immediate type from reflect.TypeOf.
Map(interface{}) TypeMapper
// Maps the interface{} value based on the pointer of an Interface provided.
// This is really only useful for mapping a value as an interface, as interfaces
// cannot at this time be referenced directly without a pointer.
MapTo(interface{}, interface{}) TypeMapper
// Provides a possibility to directly insert a mapping based on type and value.
// This makes it possible to directly map type arguments not possible to instantiate
// with reflect like unidirectional channels.
Set(reflect.Type, reflect.Value) TypeMapper
// Returns the Value that is mapped to the current type. Returns a zeroed Value if
// the Type has not been mapped.
Get(reflect.Type) reflect.Value
}
```
TypeMapper represents an interface for mapping interface{} values based on type.

187
vendor/github.com/codegangsta/inject/inject.go сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,187 @@
// Package inject provides utilities for mapping and injecting dependencies in various ways.
package inject
import (
"fmt"
"reflect"
)
// Injector represents an interface for mapping and injecting dependencies into structs
// and function arguments.
type Injector interface {
Applicator
Invoker
TypeMapper
// SetParent sets the parent of the injector. If the injector cannot find a
// dependency in its Type map it will check its parent before returning an
// error.
SetParent(Injector)
}
// Applicator represents an interface for mapping dependencies to a struct.
type Applicator interface {
// Maps dependencies in the Type map to each field in the struct
// that is tagged with 'inject'. Returns an error if the injection
// fails.
Apply(interface{}) error
}
// Invoker represents an interface for calling functions via reflection.
type Invoker interface {
// Invoke attempts to call the interface{} provided as a function,
// providing dependencies for function arguments based on Type. Returns
// a slice of reflect.Value representing the returned values of the function.
// Returns an error if the injection fails.
Invoke(interface{}) ([]reflect.Value, error)
}
// TypeMapper represents an interface for mapping interface{} values based on type.
type TypeMapper interface {
// Maps the interface{} value based on its immediate type from reflect.TypeOf.
Map(interface{}) TypeMapper
// Maps the interface{} value based on the pointer of an Interface provided.
// This is really only useful for mapping a value as an interface, as interfaces
// cannot at this time be referenced directly without a pointer.
MapTo(interface{}, interface{}) TypeMapper
// Provides a possibility to directly insert a mapping based on type and value.
// This makes it possible to directly map type arguments not possible to instantiate
// with reflect like unidirectional channels.
Set(reflect.Type, reflect.Value) TypeMapper
// Returns the Value that is mapped to the current type. Returns a zeroed Value if
// the Type has not been mapped.
Get(reflect.Type) reflect.Value
}
type injector struct {
values map[reflect.Type]reflect.Value
parent Injector
}
// InterfaceOf dereferences a pointer to an Interface type.
// It panics if value is not an pointer to an interface.
func InterfaceOf(value interface{}) reflect.Type {
t := reflect.TypeOf(value)
for t.Kind() == reflect.Ptr {
t = t.Elem()
}
if t.Kind() != reflect.Interface {
panic("Called inject.InterfaceOf with a value that is not a pointer to an interface. (*MyInterface)(nil)")
}
return t
}
// New returns a new Injector.
func New() Injector {
return &injector{
values: make(map[reflect.Type]reflect.Value),
}
}
// Invoke attempts to call the interface{} provided as a function,
// providing dependencies for function arguments based on Type.
// Returns a slice of reflect.Value representing the returned values of the function.
// Returns an error if the injection fails.
// It panics if f is not a function
func (inj *injector) Invoke(f interface{}) ([]reflect.Value, error) {
t := reflect.TypeOf(f)
var in = make([]reflect.Value, t.NumIn()) //Panic if t is not kind of Func
for i := 0; i < t.NumIn(); i++ {
argType := t.In(i)
val := inj.Get(argType)
if !val.IsValid() {
return nil, fmt.Errorf("Value not found for type %v", argType)
}
in[i] = val
}
return reflect.ValueOf(f).Call(in), nil
}
// Maps dependencies in the Type map to each field in the struct
// that is tagged with 'inject'.
// Returns an error if the injection fails.
func (inj *injector) Apply(val interface{}) error {
v := reflect.ValueOf(val)
for v.Kind() == reflect.Ptr {
v = v.Elem()
}
if v.Kind() != reflect.Struct {
return nil // Should not panic here ?
}
t := v.Type()
for i := 0; i < v.NumField(); i++ {
f := v.Field(i)
structField := t.Field(i)
if f.CanSet() && (structField.Tag == "inject" || structField.Tag.Get("inject") != "") {
ft := f.Type()
v := inj.Get(ft)
if !v.IsValid() {
return fmt.Errorf("Value not found for type %v", ft)
}
f.Set(v)
}
}
return nil
}
// Maps the concrete value of val to its dynamic type using reflect.TypeOf,
// It returns the TypeMapper registered in.
func (i *injector) Map(val interface{}) TypeMapper {
i.values[reflect.TypeOf(val)] = reflect.ValueOf(val)
return i
}
func (i *injector) MapTo(val interface{}, ifacePtr interface{}) TypeMapper {
i.values[InterfaceOf(ifacePtr)] = reflect.ValueOf(val)
return i
}
// Maps the given reflect.Type to the given reflect.Value and returns
// the Typemapper the mapping has been registered in.
func (i *injector) Set(typ reflect.Type, val reflect.Value) TypeMapper {
i.values[typ] = val
return i
}
func (i *injector) Get(t reflect.Type) reflect.Value {
val := i.values[t]
if val.IsValid() {
return val
}
// no concrete types found, try to find implementors
// if t is an interface
if t.Kind() == reflect.Interface {
for k, v := range i.values {
if k.Implements(t) {
val = v
break
}
}
}
// Still no type found, try to look it up on the parent
if !val.IsValid() && i.parent != nil {
val = i.parent.Get(t)
}
return val
}
func (i *injector) SetParent(parent Injector) {
i.parent = parent
}

85
vendor/github.com/codegangsta/inject/translations/README_zh_cn.md сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,85 @@
# inject
--
import "github.com/codegangsta/inject"
inject包提供了多种对实体的映射和依赖注入方式。
## 用法
#### func InterfaceOf
```go
func InterfaceOf(value interface{}) reflect.Type
```
函数InterfaceOf返回指向接口类型的指针。如果传入的value值不是指向接口的指针将抛出一个panic异常。
#### type Applicator
```go
type Applicator interface {
// 在Type map中维持对结构体中每个域的引用并用'inject'来标记
// 如果注入失败将会返回一个error.
Apply(interface{}) error
}
```
Applicator接口表示到结构体的依赖映射关系。
#### type Injector
```go
type Injector interface {
Applicator
Invoker
TypeMapper
// SetParent用来设置父injector. 如果在当前injector的Type map中找不到依赖
// 将会继续从它的父injector中找直到返回error.
SetParent(Injector)
}
```
Injector接口表示对结构体、函数参数的映射和依赖注入。
#### func New
```go
func New() Injector
```
New创建并返回一个Injector.
#### type Invoker
```go
type Invoker interface {
// Invoke尝试将interface{}作为一个函数来调用并基于Type为函数提供参数。
// 它将返回reflect.Value的切片其中存放原函数的返回值。
// 如果注入失败则返回error.
Invoke(interface{}) ([]reflect.Value, error)
}
```
Invoker接口表示通过反射进行函数调用。
#### type TypeMapper
```go
type TypeMapper interface {
// 基于调用reflect.TypeOf得到的类型映射interface{}的值。
Map(interface{}) TypeMapper
// 基于提供的接口的指针映射interface{}的值。
// 该函数仅用来将一个值映射为接口,因为接口无法不通过指针而直接引用到。
MapTo(interface{}, interface{}) TypeMapper
// 为直接插入基于类型和值的map提供一种可能性。
// 它使得这一类直接映射成为可能:无法通过反射直接实例化的类型参数,如单向管道。
Set(reflect.Type, reflect.Value) TypeMapper
// 返回映射到当前类型的Value. 如果Type没被映射将返回对应的零值。
Get(reflect.Type) reflect.Value
}
```
TypeMapper接口用来表示基于类型到接口值的映射。
## 译者
张强 (qqbunny@yeah.net)

3
vendor/github.com/codegangsta/inject/update_readme.sh сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,3 @@
#!/bin/bash
go get github.com/robertkrimen/godocdown/godocdown
godocdown > README.md

258
vendor/github.com/outbrain/golib/log/log.go сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,258 @@
/*
Copyright 2014 Outbrain Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package log
import (
"errors"
"fmt"
"log/syslog"
"os"
"runtime/debug"
"time"
)
// LogLevel indicates the severity of a log entry
type LogLevel int
func (this LogLevel) String() string {
switch this {
case FATAL:
return "FATAL"
case CRITICAL:
return "CRITICAL"
case ERROR:
return "ERROR"
case WARNING:
return "WARNING"
case NOTICE:
return "NOTICE"
case INFO:
return "INFO"
case DEBUG:
return "DEBUG"
}
return "unknown"
}
func LogLevelFromString(logLevelName string) (LogLevel, error) {
switch logLevelName {
case "FATAL":
return FATAL, nil
case "CRITICAL":
return CRITICAL, nil
case "ERROR":
return ERROR, nil
case "WARNING":
return WARNING, nil
case "NOTICE":
return NOTICE, nil
case "INFO":
return INFO, nil
case "DEBUG":
return DEBUG, nil
}
return 0, fmt.Errorf("Unknown LogLevel name: %+v", logLevelName)
}
const (
FATAL LogLevel = iota
CRITICAL
ERROR
WARNING
NOTICE
INFO
DEBUG
)
const TimeFormat = "2006-01-02 15:04:05"
// globalLogLevel indicates the global level filter for all logs (only entries with level equals or higher
// than this value will be logged)
var globalLogLevel LogLevel = DEBUG
var printStackTrace bool = false
// syslogWriter is optional, and defaults to nil (disabled)
var syslogLevel LogLevel = ERROR
var syslogWriter *syslog.Writer
// SetPrintStackTrace enables/disables dumping the stack upon error logging
func SetPrintStackTrace(shouldPrintStackTrace bool) {
printStackTrace = shouldPrintStackTrace
}
// SetLevel sets the global log level. Only entries with level equals or higher than
// this value will be logged
func SetLevel(logLevel LogLevel) {
globalLogLevel = logLevel
}
// GetLevel returns current global log level
func GetLevel() LogLevel {
return globalLogLevel
}
// EnableSyslogWriter enables, if possible, writes to syslog. These will execute _in addition_ to normal logging
func EnableSyslogWriter(tag string) (err error) {
syslogWriter, err = syslog.New(syslog.LOG_ERR, tag)
if err != nil {
syslogWriter = nil
}
return err
}
// SetSyslogLevel sets the minimal syslog level. Only entries with level equals or higher than
// this value will be logged. However, this is also capped by the global log level. That is,
// messages with lower level than global-log-level will be discarded at any case.
func SetSyslogLevel(logLevel LogLevel) {
syslogLevel = logLevel
}
// logFormattedEntry nicely formats and emits a log entry
func logFormattedEntry(logLevel LogLevel, message string, args ...interface{}) string {
if logLevel > globalLogLevel {
return ""
}
msgArgs := fmt.Sprintf(message, args...)
entryString := fmt.Sprintf("%s %s %s", time.Now().Format(TimeFormat), logLevel, msgArgs)
fmt.Fprintln(os.Stderr, entryString)
if syslogWriter != nil {
go func() error {
if logLevel > syslogLevel {
return nil
}
switch logLevel {
case FATAL:
return syslogWriter.Emerg(msgArgs)
case CRITICAL:
return syslogWriter.Crit(msgArgs)
case ERROR:
return syslogWriter.Err(msgArgs)
case WARNING:
return syslogWriter.Warning(msgArgs)
case NOTICE:
return syslogWriter.Notice(msgArgs)
case INFO:
return syslogWriter.Info(msgArgs)
case DEBUG:
return syslogWriter.Debug(msgArgs)
}
return nil
}()
}
return entryString
}
// logEntry emits a formatted log entry
func logEntry(logLevel LogLevel, message string, args ...interface{}) string {
entryString := message
for _, s := range args {
entryString += fmt.Sprintf(" %s", s)
}
return logFormattedEntry(logLevel, entryString)
}
// logErrorEntry emits a log entry based on given error object
func logErrorEntry(logLevel LogLevel, err error) error {
if err == nil {
// No error
return nil
}
entryString := fmt.Sprintf("%+v", err)
logEntry(logLevel, entryString)
if printStackTrace {
debug.PrintStack()
}
return err
}
func Debug(message string, args ...interface{}) string {
return logEntry(DEBUG, message, args...)
}
func Debugf(message string, args ...interface{}) string {
return logFormattedEntry(DEBUG, message, args...)
}
func Info(message string, args ...interface{}) string {
return logEntry(INFO, message, args...)
}
func Infof(message string, args ...interface{}) string {
return logFormattedEntry(INFO, message, args...)
}
func Notice(message string, args ...interface{}) string {
return logEntry(NOTICE, message, args...)
}
func Noticef(message string, args ...interface{}) string {
return logFormattedEntry(NOTICE, message, args...)
}
func Warning(message string, args ...interface{}) error {
return errors.New(logEntry(WARNING, message, args...))
}
func Warningf(message string, args ...interface{}) error {
return errors.New(logFormattedEntry(WARNING, message, args...))
}
func Error(message string, args ...interface{}) error {
return errors.New(logEntry(ERROR, message, args...))
}
func Errorf(message string, args ...interface{}) error {
return errors.New(logFormattedEntry(ERROR, message, args...))
}
func Errore(err error) error {
return logErrorEntry(ERROR, err)
}
func Critical(message string, args ...interface{}) error {
return errors.New(logEntry(CRITICAL, message, args...))
}
func Criticalf(message string, args ...interface{}) error {
return errors.New(logFormattedEntry(CRITICAL, message, args...))
}
func Criticale(err error) error {
return logErrorEntry(CRITICAL, err)
}
// Fatal emits a FATAL level entry and exists the program
func Fatal(message string, args ...interface{}) error {
logEntry(FATAL, message, args...)
os.Exit(1)
return errors.New(logEntry(CRITICAL, message, args...))
}
// Fatalf emits a FATAL level entry and exists the program
func Fatalf(message string, args ...interface{}) error {
logFormattedEntry(FATAL, message, args...)
os.Exit(1)
return errors.New(logFormattedEntry(CRITICAL, message, args...))
}
// Fatale emits a FATAL level entry and exists the program
func Fatale(err error) error {
logErrorEntry(FATAL, err)
os.Exit(1)
return err
}

119
vendor/github.com/outbrain/golib/math/math.go сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,119 @@
/*
Copyright 2014 Shlomi Noach.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package math
func MinInt(i1, i2 int) int {
if i1 < i2 {
return i1
}
return i2
}
func MaxInt(i1, i2 int) int {
if i1 > i2 {
return i1
}
return i2
}
func MinInt64(i1, i2 int64) int64 {
if i1 < i2 {
return i1
}
return i2
}
func MaxInt64(i1, i2 int64) int64 {
if i1 > i2 {
return i1
}
return i2
}
func MinUInt(i1, i2 uint) uint {
if i1 < i2 {
return i1
}
return i2
}
func MaxUInt(i1, i2 uint) uint {
if i1 > i2 {
return i1
}
return i2
}
func MinUInt64(i1, i2 uint64) uint64 {
if i1 < i2 {
return i1
}
return i2
}
func MaxUInt64(i1, i2 uint64) uint64 {
if i1 > i2 {
return i1
}
return i2
}
func MinString(i1, i2 string) string {
if i1 < i2 {
return i1
}
return i2
}
func MaxString(i1, i2 string) string {
if i1 > i2 {
return i1
}
return i2
}
// TernaryString acts like a "? :" C-style ternary operator for strings
func TernaryString(condition bool, resTrue string, resFalse string) string {
if condition {
return resTrue
}
return resFalse
}
// TernaryString acts like a "? :" C-style ternary operator for ints
func TernaryInt(condition bool, resTrue int, resFalse int) int {
if condition {
return resTrue
}
return resFalse
}
// AbsInt is an ABS function for int type
func AbsInt(i int) int {
if i >= 0 {
return i
}
return -i
}
// AbsInt64 is an ABS function for int64 type
func AbsInt64(i int64) int64 {
if i >= 0 {
return i
}
return -i
}

333
vendor/github.com/outbrain/golib/sqlutils/sqlutils.go сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,333 @@
/*
Copyright 2014 Outbrain Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package sqlutils
import (
"database/sql"
"encoding/json"
"errors"
"fmt"
_ "github.com/go-sql-driver/mysql"
"github.com/outbrain/golib/log"
"strconv"
"strings"
"sync"
)
// RowMap represents one row in a result set. Its objective is to allow
// for easy, typed getters by column name.
type RowMap map[string]CellData
// Cell data is the result of a single (atomic) column in a single row
type CellData sql.NullString
func (this *CellData) MarshalJSON() ([]byte, error) {
if this.Valid {
return json.Marshal(this.String)
} else {
return json.Marshal(nil)
}
}
func (this *CellData) NullString() *sql.NullString {
return (*sql.NullString)(this)
}
// RowData is the result of a single row, in positioned array format
type RowData []CellData
// MarshalJSON will marshal this map as JSON
func (this *RowData) MarshalJSON() ([]byte, error) {
cells := make([](*CellData), len(*this), len(*this))
for i, val := range *this {
d := CellData(val)
cells[i] = &d
}
return json.Marshal(cells)
}
// ResultData is an ordered row set of RowData
type ResultData []RowData
var EmptyResultData = ResultData{}
func (this *RowMap) GetString(key string) string {
return (*this)[key].String
}
// GetStringD returns a string from the map, or a default value if the key does not exist
func (this *RowMap) GetStringD(key string, def string) string {
if cell, ok := (*this)[key]; ok {
return cell.String
}
return def
}
func (this *RowMap) GetInt64(key string) int64 {
res, _ := strconv.ParseInt(this.GetString(key), 10, 0)
return res
}
func (this *RowMap) GetNullInt64(key string) sql.NullInt64 {
i, err := strconv.ParseInt(this.GetString(key), 10, 0)
if err == nil {
return sql.NullInt64{Int64: i, Valid: true}
} else {
return sql.NullInt64{Valid: false}
}
}
func (this *RowMap) GetInt(key string) int {
res, _ := strconv.Atoi(this.GetString(key))
return res
}
func (this *RowMap) GetIntD(key string, def int) int {
res, err := strconv.Atoi(this.GetString(key))
if err != nil {
return def
}
return res
}
func (this *RowMap) GetUint(key string) uint {
res, _ := strconv.Atoi(this.GetString(key))
return uint(res)
}
func (this *RowMap) GetUintD(key string, def uint) uint {
res, err := strconv.Atoi(this.GetString(key))
if err != nil {
return def
}
return uint(res)
}
func (this *RowMap) GetBool(key string) bool {
return this.GetInt(key) != 0
}
// knownDBs is a DB cache by uri
var knownDBs map[string]*sql.DB = make(map[string]*sql.DB)
var knownDBsMutex = &sync.Mutex{}
// GetDB returns a DB instance based on uri.
// bool result indicates whether the DB was returned from cache; err
func GetDB(mysql_uri string) (*sql.DB, bool, error) {
knownDBsMutex.Lock()
defer func() {
knownDBsMutex.Unlock()
}()
var exists bool
if _, exists = knownDBs[mysql_uri]; !exists {
if db, err := sql.Open("mysql", mysql_uri); err == nil {
knownDBs[mysql_uri] = db
} else {
return db, exists, err
}
}
return knownDBs[mysql_uri], exists, nil
}
// RowToArray is a convenience function, typically not called directly, which maps a
// single read database row into a NullString
func RowToArray(rows *sql.Rows, columns []string) []CellData {
buff := make([]interface{}, len(columns))
data := make([]CellData, len(columns))
for i, _ := range buff {
buff[i] = data[i].NullString()
}
rows.Scan(buff...)
return data
}
// ScanRowsToArrays is a convenience function, typically not called directly, which maps rows
// already read from the databse into arrays of NullString
func ScanRowsToArrays(rows *sql.Rows, on_row func([]CellData) error) error {
columns, _ := rows.Columns()
for rows.Next() {
arr := RowToArray(rows, columns)
err := on_row(arr)
if err != nil {
return err
}
}
return nil
}
func rowToMap(row []CellData, columns []string) map[string]CellData {
m := make(map[string]CellData)
for k, data_col := range row {
m[columns[k]] = data_col
}
return m
}
// ScanRowsToMaps is a convenience function, typically not called directly, which maps rows
// already read from the databse into RowMap entries.
func ScanRowsToMaps(rows *sql.Rows, on_row func(RowMap) error) error {
columns, _ := rows.Columns()
err := ScanRowsToArrays(rows, func(arr []CellData) error {
m := rowToMap(arr, columns)
err := on_row(m)
if err != nil {
return err
}
return nil
})
return err
}
// QueryRowsMap is a convenience function allowing querying a result set while poviding a callback
// function activated per read row.
func QueryRowsMap(db *sql.DB, query string, on_row func(RowMap) error, args ...interface{}) error {
var err error
defer func() {
if derr := recover(); derr != nil {
err = errors.New(fmt.Sprintf("QueryRowsMap unexpected error: %+v", derr))
}
}()
rows, err := db.Query(query, args...)
defer rows.Close()
if err != nil && err != sql.ErrNoRows {
return log.Errore(err)
}
err = ScanRowsToMaps(rows, on_row)
return err
}
// queryResultData returns a raw array of rows for a given query, optionally reading and returning column names
func queryResultData(db *sql.DB, query string, retrieveColumns bool, args ...interface{}) (ResultData, []string, error) {
var err error
defer func() {
if derr := recover(); derr != nil {
err = errors.New(fmt.Sprintf("QueryRowsMap unexpected error: %+v", derr))
}
}()
columns := []string{}
rows, err := db.Query(query, args...)
defer rows.Close()
if err != nil && err != sql.ErrNoRows {
return EmptyResultData, columns, log.Errore(err)
}
if retrieveColumns {
// Don't pay if you don't want to
columns, _ = rows.Columns()
}
resultData := ResultData{}
err = ScanRowsToArrays(rows, func(rowData []CellData) error {
resultData = append(resultData, rowData)
return nil
})
return resultData, columns, err
}
// QueryResultData returns a raw array of rows
func QueryResultData(db *sql.DB, query string, args ...interface{}) (ResultData, error) {
resultData, _, err := queryResultData(db, query, false, args...)
return resultData, err
}
// QueryResultDataNamed returns a raw array of rows, with column names
func QueryResultDataNamed(db *sql.DB, query string, args ...interface{}) (ResultData, []string, error) {
return queryResultData(db, query, true, args...)
}
// QueryRowsMapBuffered reads data from the database into a buffer, and only then applies the given function per row.
// This allows the application to take its time with processing the data, albeit consuming as much memory as required by
// the result set.
func QueryRowsMapBuffered(db *sql.DB, query string, on_row func(RowMap) error, args ...interface{}) error {
resultData, columns, err := queryResultData(db, query, true, args...)
if err != nil {
// Already logged
return err
}
for _, row := range resultData {
err = on_row(rowToMap(row, columns))
if err != nil {
return err
}
}
return nil
}
// ExecNoPrepare executes given query using given args on given DB, without using prepared statements.
func ExecNoPrepare(db *sql.DB, query string, args ...interface{}) (sql.Result, error) {
var err error
defer func() {
if derr := recover(); derr != nil {
err = errors.New(fmt.Sprintf("ExecNoPrepare unexpected error: %+v", derr))
}
}()
var res sql.Result
res, err = db.Exec(query, args...)
if err != nil {
log.Errore(err)
}
return res, err
}
// ExecQuery executes given query using given args on given DB. It will safele prepare, execute and close
// the statement.
func execInternal(silent bool, db *sql.DB, query string, args ...interface{}) (sql.Result, error) {
var err error
defer func() {
if derr := recover(); derr != nil {
err = errors.New(fmt.Sprintf("execInternal unexpected error: %+v", derr))
}
}()
stmt, err := db.Prepare(query)
if err != nil {
return nil, err
}
defer stmt.Close()
var res sql.Result
res, err = stmt.Exec(args...)
if err != nil && !silent {
log.Errore(err)
}
return res, err
}
// Exec executes given query using given args on given DB. It will safele prepare, execute and close
// the statement.
func Exec(db *sql.DB, query string, args ...interface{}) (sql.Result, error) {
return execInternal(false, db, query, args...)
}
// ExecSilently acts like Exec but does not report any error
func ExecSilently(db *sql.DB, query string, args ...interface{}) (sql.Result, error) {
return execInternal(true, db, query, args...)
}
func InClauseStringValues(terms []string) string {
quoted := []string{}
for _, s := range terms {
quoted = append(quoted, fmt.Sprintf("'%s'", strings.Replace(s, ",", "''", -1)))
}
return strings.Join(quoted, ", ")
}
// Convert variable length arguments into arguments array
func Args(args ...interface{}) []interface{} {
return args
}

76
vendor/github.com/outbrain/golib/tests/spec.go сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,76 @@
package tests
import (
"testing"
)
// Spec is an access point to test Expections
type Spec struct {
t *testing.T
}
// S generates a spec. You will want to use it once in a test file, once in a test or once per each check
func S(t *testing.T) *Spec {
return &Spec{t: t}
}
// ExpectNil expects given value to be nil, or errors
func (spec *Spec) ExpectNil(actual interface{}) {
if actual == nil {
return
}
spec.t.Errorf("Expected %+v to be nil", actual)
}
// ExpectNotNil expects given value to be not nil, or errors
func (spec *Spec) ExpectNotNil(actual interface{}) {
if actual != nil {
return
}
spec.t.Errorf("Expected %+v to be not nil", actual)
}
// ExpectEquals expects given values to be equal (comparison via `==`), or errors
func (spec *Spec) ExpectEquals(actual, value interface{}) {
if actual == value {
return
}
spec.t.Errorf("Expected %+v, got %+v", value, actual)
}
// ExpectNotEquals expects given values to be nonequal (comparison via `==`), or errors
func (spec *Spec) ExpectNotEquals(actual, value interface{}) {
if !(actual == value) {
return
}
spec.t.Errorf("Expected not %+v", value)
}
// ExpectEqualsAny expects given actual to equal (comparison via `==`) at least one of given values, or errors
func (spec *Spec) ExpectEqualsAny(actual interface{}, values ...interface{}) {
for _, value := range values {
if actual == value {
return
}
}
spec.t.Errorf("Expected %+v to equal any of given values", actual)
}
// ExpectNotEqualsAny expects given actual to be nonequal (comparison via `==`)tp any of given values, or errors
func (spec *Spec) ExpectNotEqualsAny(actual interface{}, values ...interface{}) {
for _, value := range values {
if actual == value {
spec.t.Errorf("Expected not %+v", value)
}
}
}
// ExpectFalse expects given values to be false, or errors
func (spec *Spec) ExpectFalse(actual interface{}) {
spec.ExpectEquals(actual, false)
}
// ExpectTrue expects given values to be true, or errors
func (spec *Spec) ExpectTrue(actual interface{}) {
spec.ExpectEquals(actual, true)
}

50
vendor/github.com/outbrain/golib/util/text.go сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,50 @@
/*
Copyright 2015 Shlomi Noach.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package util
import (
"errors"
"fmt"
"regexp"
"strconv"
)
// ParseSimpleTime parses input in the format 7s, 55m, 3h, 31d, 4w (second, minute, hour, day, week)
// The time.ParseDuration() function should have done this, but it does not support "d" and "w" extensions.
func SimpleTimeToSeconds(simpleTime string) (int, error) {
if matched, _ := regexp.MatchString("^[0-9]+s$", simpleTime); matched {
i, _ := strconv.Atoi(simpleTime[0 : len(simpleTime)-1])
return i, nil
}
if matched, _ := regexp.MatchString("^[0-9]+m$", simpleTime); matched {
i, _ := strconv.Atoi(simpleTime[0 : len(simpleTime)-1])
return i * 60, nil
}
if matched, _ := regexp.MatchString("^[0-9]+h$", simpleTime); matched {
i, _ := strconv.Atoi(simpleTime[0 : len(simpleTime)-1])
return i * 60 * 60, nil
}
if matched, _ := regexp.MatchString("^[0-9]+d$", simpleTime); matched {
i, _ := strconv.Atoi(simpleTime[0 : len(simpleTime)-1])
return i * 60 * 60 * 24, nil
}
if matched, _ := regexp.MatchString("^[0-9]+w$", simpleTime); matched {
i, _ := strconv.Atoi(simpleTime[0 : len(simpleTime)-1])
return i * 60 * 60 * 24 * 7, nil
}
return 0, errors.New(fmt.Sprintf("Cannot parse simple time: %s", simpleTime))
}