Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
github
orchestrator
提交
29388b21
O
orchestrator
项目概览
github
/
orchestrator
8 个月 前同步成功
通知
18
Star
5143
Fork
916
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
O
orchestrator
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
29388b21
编写于
1月 26, 2017
作者:
S
Shlomi Noach
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
readding openark/golib without submodule
上级
e247ae04
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
966 addition
and
0 deletion
+966
-0
vendor/github.com/openark/golib/README.md
vendor/github.com/openark/golib/README.md
+9
-0
vendor/github.com/openark/golib/log/log.go
vendor/github.com/openark/golib/log/log.go
+258
-0
vendor/github.com/openark/golib/math/math.go
vendor/github.com/openark/golib/math/math.go
+119
-0
vendor/github.com/openark/golib/sqlutils/dialect.go
vendor/github.com/openark/golib/sqlutils/dialect.go
+63
-0
vendor/github.com/openark/golib/sqlutils/dialect_test.go
vendor/github.com/openark/golib/sqlutils/dialect_test.go
+58
-0
vendor/github.com/openark/golib/sqlutils/sqlutils.go
vendor/github.com/openark/golib/sqlutils/sqlutils.go
+333
-0
vendor/github.com/openark/golib/tests/spec.go
vendor/github.com/openark/golib/tests/spec.go
+76
-0
vendor/github.com/openark/golib/util/text.go
vendor/github.com/openark/golib/util/text.go
+50
-0
未找到文件。
vendor/github.com/openark/golib/README.md
0 → 100644
浏览文件 @
29388b21
Common Go libraries
To import & use:
```
go get "github.com/openark/golib/math"
go get "github.com/openark/golib/sqlutils"
go get "github.com/openark/golib/tests"
...
```
vendor/github.com/openark/golib/log/log.go
0 → 100644
浏览文件 @
29388b21
/*
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
}
vendor/github.com/openark/golib/math/math.go
0 → 100644
浏览文件 @
29388b21
/*
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
}
vendor/github.com/openark/golib/sqlutils/dialect.go
0 → 100644
浏览文件 @
29388b21
/*
Copyright 2017 GitHub 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
(
"regexp"
"strings"
)
type
regexpMap
struct
{
r
*
regexp
.
Regexp
replacement
string
}
func
(
this
*
regexpMap
)
process
(
text
string
)
(
result
string
)
{
return
this
.
r
.
ReplaceAllString
(
text
,
this
.
replacement
)
}
var
(
createTableCharset
=
rmap
(
`(?i)varchar[\s]*[(][\s]*([0-9]+)[\s]*[)] (character set|charset) [\S]+`
,
`varchar(${1})`
)
)
var
(
identifyCreateStatement
=
regexp
.
MustCompile
(
regexpSpaces
(
`(?i)^[\s]*create table`
))
)
func
rmap
(
regexpExpression
string
,
replacement
string
)
regexpMap
{
return
regexpMap
{
r
:
regexp
.
MustCompile
(
regexpSpaces
(
regexpExpression
)),
replacement
:
replacement
,
}
}
func
regexpSpaces
(
statement
string
)
string
{
return
strings
.
Replace
(
statement
,
" "
,
`[ ]+`
,
-
1
)
}
func
isCreateTable
(
statement
string
)
bool
{
return
identifyCreateStatement
.
MatchString
(
statement
)
}
func
ToSqlite3CreateTable
(
statement
string
)
(
string
,
error
)
{
statement
=
createTableCharset
.
process
(
statement
)
return
statement
,
nil
}
func
ToSqlite3Dialect
(
statement
string
)
(
translated
string
,
err
error
)
{
return
statement
,
err
}
vendor/github.com/openark/golib/sqlutils/dialect_test.go
0 → 100644
浏览文件 @
29388b21
/*
Copyright 2017 GitHub 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
(
"testing"
test
"github.com/openark/golib/tests"
)
func
init
()
{
}
func
TestIsCreateTable
(
t
*
testing
.
T
)
{
test
.
S
(
t
)
.
ExpectTrue
(
isCreateTable
(
"create table t(id int)"
))
test
.
S
(
t
)
.
ExpectTrue
(
isCreateTable
(
" create table t(id int)"
))
test
.
S
(
t
)
.
ExpectTrue
(
isCreateTable
(
"CREATE TABLE t(id int)"
))
test
.
S
(
t
)
.
ExpectTrue
(
isCreateTable
(
`
create table t(id int)
`
))
test
.
S
(
t
)
.
ExpectFalse
(
isCreateTable
(
"where create table t(id int)"
))
test
.
S
(
t
)
.
ExpectFalse
(
isCreateTable
(
"insert"
))
}
func
TestToSqlite3CreateTable
(
t
*
testing
.
T
)
{
{
statement
:=
"create table t(id int)"
result
,
err
:=
ToSqlite3CreateTable
(
statement
)
test
.
S
(
t
)
.
ExpectNil
(
err
)
test
.
S
(
t
)
.
ExpectEquals
(
result
,
statement
)
}
{
statement
:=
"create table t(id int, v varchar(123) CHARACTER SET ascii NOT NULL default '')"
result
,
err
:=
ToSqlite3CreateTable
(
statement
)
test
.
S
(
t
)
.
ExpectNil
(
err
)
test
.
S
(
t
)
.
ExpectEquals
(
result
,
"create table t(id int, v varchar(123) NOT NULL default '')"
)
}
{
statement
:=
"create table t(id int, v varchar ( 123 ) CHARACTER SET ascii NOT NULL default '')"
result
,
err
:=
ToSqlite3CreateTable
(
statement
)
test
.
S
(
t
)
.
ExpectNil
(
err
)
test
.
S
(
t
)
.
ExpectEquals
(
result
,
"create table t(id int, v varchar(123) NOT NULL default '')"
)
}
}
vendor/github.com/openark/golib/sqlutils/sqlutils.go
0 → 100644
浏览文件 @
29388b21
/*
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/openark/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
}
vendor/github.com/openark/golib/tests/spec.go
0 → 100644
浏览文件 @
29388b21
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
)
}
vendor/github.com/openark/golib/util/text.go
0 → 100644
浏览文件 @
29388b21
/*
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
))
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录