add Iterator* functions for garray; add ReplaceDir*/ReplaceFile* functions for gfile; remove gfile.Replace/ReplaceFunc functions

This commit is contained in:
John
2019-12-25 20:56:39 +08:00
parent 597f7468e9
commit a10f428715
16 changed files with 492 additions and 26 deletions

View File

@ -625,6 +625,35 @@ func (a *Array) CountValues() map[interface{}]int {
return m
}
// Iterator is alias of IteratorAsc.
func (a *Array) Iterator(f func(k int, v interface{}) bool) {
a.IteratorAsc(f)
}
// IteratorAsc iterates the array in ascending order with given callback function <f>.
// If <f> returns true, then it continues iterating; or false to stop.
func (a *Array) IteratorAsc(f func(k int, v interface{}) bool) {
a.mu.RLock()
defer a.mu.RUnlock()
for k, v := range a.array {
if !f(k, v) {
break
}
}
}
// IteratorDesc iterates the array in descending order with given callback function <f>.
// If <f> returns true, then it continues iterating; or false to stop.
func (a *Array) IteratorDesc(f func(k int, v interface{}) bool) {
a.mu.RLock()
defer a.mu.RUnlock()
for i := len(a.array) - 1; i >= 0; i-- {
if !f(i, a.array[i]) {
break
}
}
}
// String returns current array as a string, which implements like json.Marshal does.
func (a *Array) String() string {
a.mu.RLock()

View File

@ -637,6 +637,35 @@ func (a *IntArray) CountValues() map[int]int {
return m
}
// Iterator is alias of IteratorAsc.
func (a *IntArray) Iterator(f func(k int, v int) bool) {
a.IteratorAsc(f)
}
// IteratorAsc iterates the array in ascending order with given callback function <f>.
// If <f> returns true, then it continues iterating; or false to stop.
func (a *IntArray) IteratorAsc(f func(k int, v int) bool) {
a.mu.RLock()
defer a.mu.RUnlock()
for k, v := range a.array {
if !f(k, v) {
break
}
}
}
// IteratorDesc iterates the array in descending order with given callback function <f>.
// If <f> returns true, then it continues iterating; or false to stop.
func (a *IntArray) IteratorDesc(f func(k int, v int) bool) {
a.mu.RLock()
defer a.mu.RUnlock()
for i := len(a.array) - 1; i >= 0; i-- {
if !f(i, a.array[i]) {
break
}
}
}
// String returns current array as a string, which implements like json.Marshal does.
func (a *IntArray) String() string {
return "[" + a.Join(",") + "]"

View File

@ -622,6 +622,35 @@ func (a *StrArray) CountValues() map[string]int {
return m
}
// Iterator is alias of IteratorAsc.
func (a *StrArray) Iterator(f func(k int, v string) bool) {
a.IteratorAsc(f)
}
// IteratorAsc iterates the array in ascending order with given callback function <f>.
// If <f> returns true, then it continues iterating; or false to stop.
func (a *StrArray) IteratorAsc(f func(k int, v string) bool) {
a.mu.RLock()
defer a.mu.RUnlock()
for k, v := range a.array {
if !f(k, v) {
break
}
}
}
// IteratorDesc iterates the array in descending order with given callback function <f>.
// If <f> returns true, then it continues iterating; or false to stop.
func (a *StrArray) IteratorDesc(f func(k int, v string) bool) {
a.mu.RLock()
defer a.mu.RUnlock()
for i := len(a.array) - 1; i >= 0; i-- {
if !f(i, a.array[i]) {
break
}
}
}
// String returns current array as a string, which implements like json.Marshal does.
func (a *StrArray) String() string {
a.mu.RLock()

View File

@ -570,6 +570,35 @@ func (a *SortedArray) CountValues() map[interface{}]int {
return m
}
// Iterator is alias of IteratorAsc.
func (a *SortedArray) Iterator(f func(k int, v interface{}) bool) {
a.IteratorAsc(f)
}
// IteratorAsc iterates the array in ascending order with given callback function <f>.
// If <f> returns true, then it continues iterating; or false to stop.
func (a *SortedArray) IteratorAsc(f func(k int, v interface{}) bool) {
a.mu.RLock()
defer a.mu.RUnlock()
for k, v := range a.array {
if !f(k, v) {
break
}
}
}
// IteratorDesc iterates the array in descending order with given callback function <f>.
// If <f> returns true, then it continues iterating; or false to stop.
func (a *SortedArray) IteratorDesc(f func(k int, v interface{}) bool) {
a.mu.RLock()
defer a.mu.RUnlock()
for i := len(a.array) - 1; i >= 0; i-- {
if !f(i, a.array[i]) {
break
}
}
}
// String returns current array as a string, which implements like json.Marshal does.
func (a *SortedArray) String() string {
a.mu.RLock()

View File

@ -562,6 +562,35 @@ func (a *SortedIntArray) CountValues() map[int]int {
return m
}
// Iterator is alias of IteratorAsc.
func (a *SortedIntArray) Iterator(f func(k int, v int) bool) {
a.IteratorAsc(f)
}
// IteratorAsc iterates the array in ascending order with given callback function <f>.
// If <f> returns true, then it continues iterating; or false to stop.
func (a *SortedIntArray) IteratorAsc(f func(k int, v int) bool) {
a.mu.RLock()
defer a.mu.RUnlock()
for k, v := range a.array {
if !f(k, v) {
break
}
}
}
// IteratorDesc iterates the array in descending order with given callback function <f>.
// If <f> returns true, then it continues iterating; or false to stop.
func (a *SortedIntArray) IteratorDesc(f func(k int, v int) bool) {
a.mu.RLock()
defer a.mu.RUnlock()
for i := len(a.array) - 1; i >= 0; i-- {
if !f(i, a.array[i]) {
break
}
}
}
// String returns current array as a string, which implements like json.Marshal does.
func (a *SortedIntArray) String() string {
return "[" + a.Join(",") + "]"

View File

@ -547,6 +547,35 @@ func (a *SortedStrArray) CountValues() map[string]int {
return m
}
// Iterator is alias of IteratorAsc.
func (a *SortedStrArray) Iterator(f func(k int, v string) bool) {
a.IteratorAsc(f)
}
// IteratorAsc iterates the array in ascending order with given callback function <f>.
// If <f> returns true, then it continues iterating; or false to stop.
func (a *SortedStrArray) IteratorAsc(f func(k int, v string) bool) {
a.mu.RLock()
defer a.mu.RUnlock()
for k, v := range a.array {
if !f(k, v) {
break
}
}
}
// IteratorDesc iterates the array in descending order with given callback function <f>.
// If <f> returns true, then it continues iterating; or false to stop.
func (a *SortedStrArray) IteratorDesc(f func(k int, v string) bool) {
a.mu.RLock()
defer a.mu.RUnlock()
for i := len(a.array) - 1; i >= 0; i-- {
if !f(i, a.array[i]) {
break
}
}
}
// String returns current array as a string, which implements like json.Marshal does.
func (a *SortedStrArray) String() string {
a.mu.RLock()

View File

@ -450,3 +450,50 @@ func TestArray_Json(t *testing.T) {
gtest.Assert(user.Scores, data["Scores"])
})
}
func TestArray_Iterator(t *testing.T) {
slice := g.Slice{"a", "b", "d", "c"}
array := garray.NewArrayFrom(slice)
gtest.Case(t, func() {
array.Iterator(func(k int, v interface{}) bool {
gtest.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
array.IteratorAsc(func(k int, v interface{}) bool {
gtest.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
array.IteratorDesc(func(k int, v interface{}) bool {
gtest.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
index := 0
array.Iterator(func(k int, v interface{}) bool {
index++
return false
})
gtest.Assert(index, 1)
})
gtest.Case(t, func() {
index := 0
array.IteratorAsc(func(k int, v interface{}) bool {
index++
return false
})
gtest.Assert(index, 1)
})
gtest.Case(t, func() {
index := 0
array.IteratorDesc(func(k int, v interface{}) bool {
index++
return false
})
gtest.Assert(index, 1)
})
}

View File

@ -484,3 +484,50 @@ func TestIntArray_Json(t *testing.T) {
gtest.Assert(user.Scores, data["Scores"])
})
}
func TestIntArray_Iterator(t *testing.T) {
slice := g.SliceInt{10, 20, 30, 40}
array := garray.NewIntArrayFrom(slice)
gtest.Case(t, func() {
array.Iterator(func(k int, v int) bool {
gtest.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
array.IteratorAsc(func(k int, v int) bool {
gtest.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
array.IteratorDesc(func(k int, v int) bool {
gtest.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
index := 0
array.Iterator(func(k int, v int) bool {
index++
return false
})
gtest.Assert(index, 1)
})
gtest.Case(t, func() {
index := 0
array.IteratorAsc(func(k int, v int) bool {
index++
return false
})
gtest.Assert(index, 1)
})
gtest.Case(t, func() {
index := 0
array.IteratorDesc(func(k int, v int) bool {
index++
return false
})
gtest.Assert(index, 1)
})
}

View File

@ -488,3 +488,50 @@ func TestStrArray_Json(t *testing.T) {
gtest.Assert(user.Scores, data["Scores"])
})
}
func TestStrArray_Iterator(t *testing.T) {
slice := g.SliceStr{"a", "b", "d", "c"}
array := garray.NewStrArrayFrom(slice)
gtest.Case(t, func() {
array.Iterator(func(k int, v string) bool {
gtest.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
array.IteratorAsc(func(k int, v string) bool {
gtest.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
array.IteratorDesc(func(k int, v string) bool {
gtest.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
index := 0
array.Iterator(func(k int, v string) bool {
index++
return false
})
gtest.Assert(index, 1)
})
gtest.Case(t, func() {
index := 0
array.IteratorAsc(func(k int, v string) bool {
index++
return false
})
gtest.Assert(index, 1)
})
gtest.Case(t, func() {
index := 0
array.IteratorDesc(func(k int, v string) bool {
index++
return false
})
gtest.Assert(index, 1)
})
}

View File

@ -587,3 +587,50 @@ func TestSortedArray_Json(t *testing.T) {
gtest.AssertIN(user.Scores.PopLeft(), data["Scores"])
})
}
func TestSortedArray_Iterator(t *testing.T) {
slice := g.Slice{"a", "b", "d", "c"}
array := garray.NewSortedArrayFrom(slice, gutil.ComparatorString)
gtest.Case(t, func() {
array.Iterator(func(k int, v interface{}) bool {
gtest.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
array.IteratorAsc(func(k int, v interface{}) bool {
gtest.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
array.IteratorDesc(func(k int, v interface{}) bool {
gtest.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
index := 0
array.Iterator(func(k int, v interface{}) bool {
index++
return false
})
gtest.Assert(index, 1)
})
gtest.Case(t, func() {
index := 0
array.IteratorAsc(func(k int, v interface{}) bool {
index++
return false
})
gtest.Assert(index, 1)
})
gtest.Case(t, func() {
index := 0
array.IteratorDesc(func(k int, v interface{}) bool {
index++
return false
})
gtest.Assert(index, 1)
})
}

View File

@ -466,3 +466,50 @@ func TestSortedIntArray_Json(t *testing.T) {
gtest.Assert(user.Scores, []int{98, 99, 100})
})
}
func TestSortedIntArray_Iterator(t *testing.T) {
slice := g.SliceInt{10, 20, 30, 40}
array := garray.NewSortedIntArrayFrom(slice)
gtest.Case(t, func() {
array.Iterator(func(k int, v int) bool {
gtest.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
array.IteratorAsc(func(k int, v int) bool {
gtest.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
array.IteratorDesc(func(k int, v int) bool {
gtest.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
index := 0
array.Iterator(func(k int, v int) bool {
index++
return false
})
gtest.Assert(index, 1)
})
gtest.Case(t, func() {
index := 0
array.IteratorAsc(func(k int, v int) bool {
index++
return false
})
gtest.Assert(index, 1)
})
gtest.Case(t, func() {
index := 0
array.IteratorDesc(func(k int, v int) bool {
index++
return false
})
gtest.Assert(index, 1)
})
}

View File

@ -476,3 +476,50 @@ func TestSortedStrArray_Json(t *testing.T) {
gtest.Assert(user.Scores, []string{"A", "A", "A+"})
})
}
func TestSortedStrArray_Iterator(t *testing.T) {
slice := g.SliceStr{"a", "b", "d", "c"}
array := garray.NewSortedStrArrayFrom(slice)
gtest.Case(t, func() {
array.Iterator(func(k int, v string) bool {
gtest.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
array.IteratorAsc(func(k int, v string) bool {
gtest.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
array.IteratorDesc(func(k int, v string) bool {
gtest.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
index := 0
array.Iterator(func(k int, v string) bool {
index++
return false
})
gtest.Assert(index, 1)
})
gtest.Case(t, func() {
index := 0
array.IteratorAsc(func(k int, v string) bool {
index++
return false
})
gtest.Assert(index, 1)
})
gtest.Case(t, func() {
index := 0
array.IteratorDesc(func(k int, v string) bool {
index++
return false
})
gtest.Assert(index, 1)
})
}

View File

@ -364,6 +364,7 @@ func (l *List) Iterator(f func(e *Element) bool) {
// If <f> returns true, then it continues iterating; or false to stop.
func (l *List) IteratorAsc(f func(e *Element) bool) {
l.mu.RLock()
defer l.mu.RUnlock()
length := l.list.Len()
if length > 0 {
for i, e := 0, l.list.Front(); i < length; i, e = i+1, e.Next() {
@ -372,13 +373,13 @@ func (l *List) IteratorAsc(f func(e *Element) bool) {
}
}
}
l.mu.RUnlock()
}
// IteratorDesc iterates the list in descending order with given callback function <f>.
// If <f> returns true, then it continues iterating; or false to stop.
func (l *List) IteratorDesc(f func(e *Element) bool) {
l.mu.RLock()
defer l.mu.RUnlock()
length := l.list.Len()
if length > 0 {
for i, e := 0, l.list.Back(); i < length; i, e = i+1, e.Prev() {
@ -387,7 +388,6 @@ func (l *List) IteratorDesc(f func(e *Element) bool) {
}
}
}
l.mu.RUnlock()
}
// Join joins list elements with a string <glue>.

View File

@ -31,17 +31,6 @@ var (
lastOperatorReg = regexp.MustCompile(`[<>=]+\s*$`)
)
// 打印SQL对象(仅在debug=true时有效)
func (bs *dbBase) printSql(v *Sql) {
s := fmt.Sprintf("[%d ms] %s", v.End-v.Start, v.Format)
if v.Error != nil {
s += "\nError: " + v.Error.Error()
bs.logger.StackWithFilter(gPATH_FILTER_KEY).Error(s)
} else {
bs.logger.StackWithFilter(gPATH_FILTER_KEY).Debug(s)
}
}
// 数据库sql查询操作主要执行查询
func (bs *dbBase) Query(query string, args ...interface{}) (rows *sql.Rows, err error) {
link, err := bs.db.Slave()
@ -630,6 +619,17 @@ func (bs *dbBase) quoteString(s string) string {
return doQuoteString(s, charLeft, charRight)
}
// 打印SQL对象(仅在debug=true时有效)
func (bs *dbBase) printSql(v *Sql) {
s := fmt.Sprintf("[%d ms] %s", v.End-v.Start, v.Format)
if v.Error != nil {
s += "\nError: " + v.Error.Error()
bs.logger.StackWithFilter(gPATH_FILTER_KEY).Error(s)
} else {
bs.logger.StackWithFilter(gPATH_FILTER_KEY).Debug(s)
}
}
// 动态切换数据库
func (bs *dbBase) doSetSchema(sqlDb *sql.DB, schema string) error {
_, err := sqlDb.Exec("USE " + schema)

View File

@ -10,39 +10,48 @@ import (
"github.com/gogf/gf/text/gstr"
)
// Replace replaces content for files under <path>.
// ReplaceFile replaces content for file <path>.
func ReplaceFile(search, replace, path string) error {
return PutContents(path, gstr.Replace(GetContents(path), search, replace))
}
// ReplaceFileFunc replaces content for file <path> with callback function <f>.
func ReplaceFileFunc(f func(path, content string) string, path string) error {
data := GetContents(path)
result := f(path, data)
if len(data) != len(result) && data != result {
return PutContents(path, result)
}
return nil
}
// ReplaceDir replaces content for files under <path>.
// The parameter <pattern> specifies the file pattern which matches to be replaced.
// It does replacement recursively if given parameter <recursive> is true.
func Replace(search, replace, path, pattern string, recursive ...bool) error {
func ReplaceDir(search, replace, path, pattern string, recursive ...bool) error {
files, err := ScanDirFile(path, pattern, recursive...)
if err != nil {
return err
}
for _, file := range files {
if err = PutContents(file, gstr.Replace(GetContents(file), search, replace)); err != nil {
if err = ReplaceFile(search, replace, file); err != nil {
return err
}
}
return err
}
// ReplaceFunc replaces content for files under <path> with callback function <f>.
// ReplaceDirFunc replaces content for files under <path> with callback function <f>.
// The parameter <pattern> specifies the file pattern which matches to be replaced.
// It does replacement recursively if given parameter <recursive> is true.
func ReplaceFunc(f func(path, content string) string, path, pattern string, recursive ...bool) error {
func ReplaceDirFunc(f func(path, content string) string, path, pattern string, recursive ...bool) error {
files, err := ScanDirFile(path, pattern, recursive...)
if err != nil {
return err
}
data := ""
result := ""
for _, file := range files {
data = GetContents(file)
result = f(file, data)
if data != result {
if err = PutContents(file, result); err != nil {
return err
}
if err = ReplaceFileFunc(f, file); err != nil {
return err
}
}
return err

View File

@ -102,6 +102,7 @@ func ShellExec(cmd string, environment ...[]string) (string, error) {
buf := bytes.NewBuffer(nil)
p := NewProcess(getShell(), append([]string{getShellOption()}, parseCommand(cmd)...), environment...)
p.Stdout = buf
p.Stderr = buf
err := p.Run()
return buf.String(), err
}