From 1934a1179c9ce55aa7913d764e4cd21a38e3d79c Mon Sep 17 00:00:00 2001
From: JonLee
Date: Mon, 8 Dec 2025 20:43:44 +0800
Subject: [PATCH 1/2] feat: rename package name
---
.github/semantic.yml | 2 +
.github/workflows/build.yml | 46 ++
README.md | 62 +--
think/app.go => app.go | 10 +-
cache/README.md | 49 --
cache/cache.go | 38 --
cache/cache_test.go | 116 -----
cache/memory_store.go | 268 ----------
cache/memory_store_test.go | 131 -----
cache/redis_store.go | 349 -------------
cache/redis_store_test.go | 186 -------
cache/repository.go | 119 -----
cache/store.go | 39 --
cache/tag_set.go | 61 ---
cache/utils.go | 13 -
context/cookie.go | 2 +-
contract/log.go | 20 +
covprofile | 483 ++++++++++++++++++
go.mod | 11 +-
go.sum | 2 +
think/handler.go => handler.go | 4 +-
log.go | 1 +
log/formatter/formatter.go | 8 -
log/formatter/json_formatter.go | 35 --
log/formatter/line_formatter.go | 23 -
log/handler/console.go | 69 ---
log/handler/file.go | 94 ----
log/handler/file_test.go | 46 --
log/handler/handler.go | 29 --
log/handler/rotate.go | 13 -
log/handler/rotate_test.go | 34 --
log/log.go | 61 ---
log/log_test.go | 64 ---
log/logger.go | 170 ------
log/record/record.go | 63 ---
pipeline.go | 19 +-
.../recover_handler.go => recover_handler.go | 5 +-
think/response.go => response.go | 4 +-
think/route_hendler.go => route_hendler.go | 6 +-
router/middleware.go | 2 +-
router/pipeline.go | 2 +-
router/router.go | 2 +-
router/rule.go | 2 +-
router/static.go | 2 +-
session/file-handler.go | 2 +-
.../session_handler.go => session_handler.go | 8 +-
think.go | 24 +-
think_test.go | 24 +-
think/type.go => type.go | 6 +-
49 files changed, 656 insertions(+), 2173 deletions(-)
create mode 100644 .github/semantic.yml
create mode 100644 .github/workflows/build.yml
rename think/app.go => app.go (83%)
delete mode 100644 cache/README.md
delete mode 100644 cache/cache.go
delete mode 100644 cache/cache_test.go
delete mode 100644 cache/memory_store.go
delete mode 100644 cache/memory_store_test.go
delete mode 100644 cache/redis_store.go
delete mode 100644 cache/redis_store_test.go
delete mode 100644 cache/repository.go
delete mode 100644 cache/store.go
delete mode 100644 cache/tag_set.go
delete mode 100644 cache/utils.go
create mode 100644 contract/log.go
create mode 100644 covprofile
rename think/handler.go => handler.go (86%)
create mode 100644 log.go
delete mode 100644 log/formatter/formatter.go
delete mode 100644 log/formatter/json_formatter.go
delete mode 100644 log/formatter/line_formatter.go
delete mode 100644 log/handler/console.go
delete mode 100644 log/handler/file.go
delete mode 100644 log/handler/file_test.go
delete mode 100644 log/handler/handler.go
delete mode 100644 log/handler/rotate.go
delete mode 100644 log/handler/rotate_test.go
delete mode 100644 log/log.go
delete mode 100644 log/log_test.go
delete mode 100644 log/logger.go
delete mode 100644 log/record/record.go
rename think/recover_handler.go => recover_handler.go (95%)
rename think/response.go => response.go (96%)
rename think/route_hendler.go => route_hendler.go (84%)
rename think/session_handler.go => session_handler.go (88%)
rename think/type.go => type.go (50%)
diff --git a/.github/semantic.yml b/.github/semantic.yml
new file mode 100644
index 0000000..dd230f5
--- /dev/null
+++ b/.github/semantic.yml
@@ -0,0 +1,2 @@
+# Always validate the PR title AND all the commits
+titleAndCommits: true
\ No newline at end of file
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 0000000..a05fe3e
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,46 @@
+name: build
+
+on: [push, pull_request]
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ go: ['1.18', '1.22', '1.25']
+ steps:
+ - name: Set up Go
+ uses: actions/setup-go@v6
+ with:
+ go-version: ${{ matrix.go }}
+
+ - name: Check out code
+ uses: actions/checkout@v5
+
+ - name: Install dependencies
+ run: |
+ go mod download
+ - name: Run Unit tests
+ run: |
+ go test -race -covermode atomic -coverprofile=covprofile ./...
+ - name: Install goveralls
+ run: go install github.com/mattn/goveralls@latest
+ - name: Send coverage
+ env:
+ COVERALLS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: goveralls -coverprofile=covprofile -service=github
+
+ semantic-release:
+ needs: [test]
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v5
+ - uses: actions/setup-node@v6
+ with:
+ node-version: 'lts/*'
+
+ - name: Run semantic-release
+ if: github.repository == 'go-think/think' && github.event_name == 'push'
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: npx semantic-release
\ No newline at end of file
diff --git a/README.md b/README.md
index ab2d76e..2500fce 100644
--- a/README.md
+++ b/README.md
@@ -6,34 +6,34 @@
ThinkGo is a lightweight MVC framework written in Go (Golang).
-
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
@@ -43,7 +43,7 @@
The only requirement is the [Go Programming Language](https://golang.org/dl/)
```
-go get -u github.com/forgoer/thinkgo
+go get -u github.com/go-think/think
```
## Quick start
@@ -54,8 +54,8 @@ package main
import (
"fmt"
- "github.com/forgoer/thinkgo"
- "github.com/forgoer/thinkgo/think"
+ "github.com/go-think/think"
+ "github.com/go-think/think/think"
)
func main() {
@@ -248,8 +248,8 @@ Below is an example of a basic controller class.
package controller
import (
- "github.com/forgoer/thinkgo"
- "github.com/forgoer/thinkgo/context"
+ "github.com/go-think/think"
+ "github.com/go-think/think/context"
)
func Index(req *context.Request) *context.Response {
@@ -426,7 +426,7 @@ type Handler interface {
Once your driver has been implemented, you are ready to register it:
```go
-import "github.com/forgoer/thinkgo/session"
+import "github.com/go-think/think/session"
session.Extend("my_session", MySessionHandler)
```
@@ -438,7 +438,7 @@ The logger provides the eight logging levels defined in [RFC 5424]( https://tool
#### Basic Usage
```go
-import "github.com/forgoer/thinkgo/log"
+import "github.com/go-think/log"
log.Debug("log with Debug")
log.Info("log with Info")
@@ -458,12 +458,12 @@ For example, if you wish to use `daily` log files, you can do this:
```go
import (
- "github.com/forgoer/thinkgo/log"
- "github.com/forgoer/thinkgo/log/handler"
- "github.com/forgoer/thinkgo/log/record"
+ "github.com/go-think/log"
+ "github.com/go-think/log/handler"
+ "github.com/go-think/log/record"
)
-fh := handler.NewFileHandler("path/to/thinkgo.log", record.INFO)
+fh := handler.NewFileHandler("path/to/think.log", record.INFO)
log.GetLogger().PushHandler(fh)
```
@@ -476,7 +476,7 @@ ThinkGo Cache Currently supports redis, memory, and can customize the store adap
```go
import (
- "github.com/forgoer/thinkgo/cache"
+ "github.com/go-think/cache"
"time"
)
@@ -484,10 +484,10 @@ import (
var foo string
// Create a cache with memory store
-c, _ := cache.Cache(cache.NewMemoryStore("thinkgo"))
+c, _ := cache.Cache(cache.NewMemoryStore("think go"))
// Set the value
-c.Put("foo", "thinkgo", 10 * time.Minute)
+c.Put("foo", "think go", 10 * time.Minute)
// Get the string associated with the key "foo" from the cache
c.Get("foo", &foo)
@@ -506,11 +506,11 @@ cache.Remember("foo", &a, 1*time.Minute, func() interface{} {
})
```
-refer to [ThinkGo Cache]( https://github.com/forgoer/thinkgo/tree/master/cache )
+refer to [ThinkGo Cache]( https://github.com/go-think/think/tree/master/cache )
## ORM
-refer to [ThinkORM]( https://github.com/forgoer/thinkorm )
+refer to [ThinkORM]( https://github.com/go-think/think )
## License
@@ -519,5 +519,5 @@ This project is licensed under the [Apache 2.0 license](LICENSE).
## Contact
If you have any issues or feature requests, please contact us. PR is welcomed.
-- https://github.com/forgoer/thinkgo/issues
-- techqiang@gmail.com
+- https://github.com/go-think/think/issues
+- leeqvip@gmail.com
diff --git a/think/app.go b/app.go
similarity index 83%
rename from think/app.go
rename to app.go
index f00366a..41c0075 100644
--- a/think/app.go
+++ b/app.go
@@ -1,16 +1,16 @@
-package think
+package thinkgo
import (
- "github.com/forgoer/thinkgo/log"
- "github.com/forgoer/thinkgo/router"
- "github.com/forgoer/thinkgo/view"
+ "github.com/go-think/think/contract"
+ "github.com/go-think/think/router"
+ "github.com/go-think/think/view"
)
// Application the ThinkGo Application
type Application struct {
Env string
Debug bool
- Logger *log.Logger
+ Logger contract.Logger
view *view.View
route *router.Route
}
diff --git a/cache/README.md b/cache/README.md
deleted file mode 100644
index ec073df..0000000
--- a/cache/README.md
+++ /dev/null
@@ -1,49 +0,0 @@
-# ThinkGo-Cache
-
-`ThinkGo-Cache` is a cache library for Golang,it currently supports redis, memory, and can customize the store adapter.
-
-## Installation
-
-```
-go get github.com/forgoer/thinkgo/cache
-```
-
-## Usage
-
-#### Basic Usage
-
-```go
-import (
- "github.com/forgoer/thinkgo/cache"
- "time"
-)
-
-
-var foo string
-
-// Create a cache with memory store
-c, _ := cache.Cache(cache.NewMemoryStore("thinkgo"))
-
-// Set the value
-c.Put("foo", "thinkgo", 10 * time.Minute)
-
-// Get the string associated with the key "foo" from the cache
-c.Get("foo", &foo)
-
-```
-
-#### Retrieve & Store
-
-Sometimes you may wish to retrieve an item from the cache, but also store a default value if the requested item doesn't exist. For example, you may wish to retrieve all users from the cache or, if they don't exist, retrieve them from the callback and add them to the cache. You may do this using the `Remember` method:
-
-```go
-var foo int
-
-cache.Remember("foo", &a, 1*time.Minute, func() interface{} {
- return "thinkgo"
-})
-```
-
-## License
-
-This project is licensed under the `Apache 2.0 license`.
\ No newline at end of file
diff --git a/cache/cache.go b/cache/cache.go
deleted file mode 100644
index 834912b..0000000
--- a/cache/cache.go
+++ /dev/null
@@ -1,38 +0,0 @@
-package cache
-
-import (
- "errors"
- "fmt"
-)
-
-var adapters = make(map[string]Store)
-
-// Register Register a cache adapter available by the adapter name.
-func Register(name string, adapter Store) error {
- if adapter == nil {
- return errors.New("cache: Register adapter is nil")
- }
- if _, ok := adapters[name]; ok {
- return errors.New("cache: Register called twice for adapter " + name)
- }
- adapters[name] = adapter
- return nil
-}
-
-// NewCache Create a new cache by adapter name.
-func Cache(adapter interface{}) (*Repository, error) {
- var store Store
- switch adapter.(type) {
- case string:
- var ok bool
- store, ok = adapters[adapter.(string)]
- if !ok {
- err := fmt.Errorf("cache: unknown adapter name %q (forgot to import?)", adapter.(string))
- return nil, err
- }
- case Store:
- store = adapter.(Store)
- }
-
- return NewRepository(store), nil
-}
diff --git a/cache/cache_test.go b/cache/cache_test.go
deleted file mode 100644
index f8f88d3..0000000
--- a/cache/cache_test.go
+++ /dev/null
@@ -1,116 +0,0 @@
-package cache
-
-import (
- "fmt"
- "testing"
- "time"
-
- "github.com/gomodule/redigo/redis"
- "github.com/stretchr/testify/assert"
-)
-
-type Foo struct {
- Name string `json:"name"`
- Age int `json:"age"`
-}
-
-func testCache(t *testing.T, cache *Repository) {
- var a int
- var b string
- var c Foo
-
- cache.Clear()
-
- assert.Error(t, cache.Get("a", &a))
- assert.Error(t, cache.Get("b", &b))
-
- assert.NoError(t, cache.Put("a", 1, 10*time.Minute))
- assert.NoError(t, cache.Put("b", "thinkgo", 10*time.Minute))
-
- assert.True(t, cache.Has("a"))
- assert.True(t, cache.Has("b"))
-
- assert.NoError(t, cache.Get("a", &a))
- assert.Equal(t, a, 1)
- assert.NoError(t, cache.Get("b", &b))
- assert.Equal(t, b, "thinkgo")
-
- assert.NoError(t, cache.Pull("b", &b))
- assert.Equal(t, b, "thinkgo")
- assert.False(t, cache.Has("b"))
-
- assert.NoError(t, cache.Set("b", "think go", 10*time.Minute))
- assert.Error(t, cache.Add("b", "think go", 10*time.Minute))
-
- assert.True(t, cache.Has("b"))
- assert.NoError(t, cache.Forget("b"))
- assert.False(t, cache.Has("b"))
-
- assert.NoError(t, cache.Put("c", Foo{
- Name: "thinkgo",
- Age:100,
- }, 10*time.Minute))
- assert.NoError(t,cache.Get("c", &c))
- fmt.Println(c)
- assert.Equal(t, c.Name , "thinkgo")
- assert.Equal(t, c.Age , 100)
- assert.NoError(t, cache.Delete("c"))
- assert.False(t, cache.Has("c"))
-
- _, ok := cache.GetStore().(Store)
- assert.True(t, ok)
-
- assert.NoError(t, cache.Clear())
- assert.False(t, cache.Has("a"))
- assert.False(t, cache.Has("b"))
-
- assert.NoError(t, cache.Remember("a", &a, 1*time.Minute, func() interface{} {
- return 1000
- }))
-
- assert.Equal(t, a, 1000)
-
- assert.NoError(t,cache.Remember("b", &b, 1*time.Minute, func() interface{} {
- return "hello thinkgo"
- }))
-
- assert.Equal(t, b, "hello thinkgo")
-}
-
-func TestMemoryCache(t *testing.T) {
- Register("memory", NewMemoryStore("thinkgo"))
-
- cache, err := Cache("memory")
-
- if err != nil {
- t.Error(err)
- }
- testCache(t, cache)
-}
-
-func TestRedisCache(t *testing.T) {
- pool := &redis.Pool{
- MaxIdle: 5,
- MaxActive: 1000,
- IdleTimeout: 300 * time.Second,
- Wait: true,
- // Other pool configuration not shown in this example.
- Dial: func() (redis.Conn, error) {
- c, err := redis.Dial("tcp", "127.0.0.1:6379")
- if err != nil {
- return nil, err
- }
- // if _, err := c.Do("AUTH", "123456"); err != nil {
- // c.Close()
- // return nil, err
- // }
- return c, nil
- },
- }
-
- cache, err := Cache(NewRedisStore(pool, "thinkgo"))
- if err != nil {
- t.Error(err)
- }
- testCache(t, cache)
-}
\ No newline at end of file
diff --git a/cache/memory_store.go b/cache/memory_store.go
deleted file mode 100644
index 259d08a..0000000
--- a/cache/memory_store.go
+++ /dev/null
@@ -1,268 +0,0 @@
-package cache
-
-import (
- "errors"
- "fmt"
- "reflect"
- "sync"
- "time"
-)
-
-type item struct {
- Object interface{}
- Expiration int64
-}
-
-// Expired Returns true if the item has expired.
-func (item item) Expired() bool {
- if item.Expiration < 0 {
- return false
- }
- return time.Now().UnixNano() > item.Expiration
-}
-
-type MemoryStore struct {
- prefix string
- items map[string]item
- mu sync.RWMutex
- cleanupTimer *time.Timer
-}
-
-// NewStore Create a memory cache store
-func NewMemoryStore(prefix string) *MemoryStore {
- s := &MemoryStore{
- items: make(map[string]item),
- }
- return s.SetPrefix(prefix)
-}
-
-// Get get cached value by key.
-// func (s *Store) Get(key string) (interface{}, error) {
-func (s *MemoryStore) Get(key string, val interface{}) error {
- s.mu.RLock()
- defer s.mu.RUnlock()
-
- item, ok := s.items[s.prefix+key]
- if !ok {
- return errors.New("not found")
- }
-
- if item.Expired() {
- return errors.New("expired")
- }
-
- rv := reflect.ValueOf(val)
- if rv.Kind() != reflect.Ptr || rv.IsNil() {
- return errors.New("invalid unmarshal")
- }
-
- rv = rv.Elem()
-
- rv.Set(reflect.ValueOf(item.Object))
-
- return nil
-}
-
-// Put set cached value with key and expire time.
-func (s *MemoryStore) Put(key string, val interface{}, timeout time.Duration) error {
- var e int64 = -1
- if timeout >= 0 {
- e = time.Now().Add(timeout).UnixNano()
- }
-
- s.mu.RLock()
- defer s.mu.RUnlock()
-
- s.items[s.prefix+key] = item{
- Object: val,
- Expiration: e,
- }
-
- if e >= 0 {
- s.DeleteExpired()
- }
-
- return nil
-}
-
-// Increment the value of an item in the cache.
-func (s *MemoryStore) Increment(key string, value ...int) (int, error) {
- s.mu.RLock()
- defer s.mu.RUnlock()
-
- var by = 1
- if len(value) > 0 {
- by = value[0]
- }
-
- exist, ok := s.items[s.prefix+key]
- if !ok {
- s.items[s.prefix+key] = item{
- Object: 1 + by,
- }
- } else {
- by = exist.Object.(int) + by
- exist.Object = by
- s.items[s.prefix+key] = exist
- }
-
- return by, nil
-}
-
-// Decrement the value of an item in the cache.
-func (s *MemoryStore) Decrement(key string, value ...int) (int, error) {
- s.mu.RLock()
- defer s.mu.RUnlock()
-
- var by = 1
- if len(value) > 0 {
- by = value[0]
- }
-
- exist, ok := s.items[s.prefix+key]
- if !ok {
- s.items[s.prefix+key] = item{
- Object: 0 - by,
- }
- } else {
- by = exist.Object.(int) - by
- exist.Object = by
- s.items[s.prefix+key] = exist
- }
-
- return by, nil
-}
-
-// Forever Store an item in the cache indefinitely.
-func (s *MemoryStore) Forever(key string, val interface{}) error {
- return s.Put(key, val, 0)
-}
-
-// Exist check cache's existence in memory.
-func (s *MemoryStore) Exist(key string) bool {
- s.mu.RLock()
- defer s.mu.RUnlock()
-
- item, ok := s.items[s.prefix+key]
-
- if item.Expired() {
- return false
- }
-
- return ok
-}
-
-// Expire set value expire time.
-func (s *MemoryStore) Expire(key string, timeout time.Duration) error {
- var e int64 = -1
- if timeout >= 0 {
- e = time.Now().Add(timeout).UnixNano()
- }
-
- s.mu.RLock()
- defer s.mu.RUnlock()
-
- if !s.Exist(key) {
- return errors.New("key not exist")
- }
-
- item := s.items[s.prefix+key]
- item.Expiration = e
- s.items[s.prefix+key] = item
-
- if e >= 0 {
- s.DeleteExpired()
- }
-
- return nil
-}
-
-// Forget Remove an item from the cache.
-func (s *MemoryStore) Forget(key string) error {
- delete(s.items, s.prefix+key)
- return nil
-}
-
-// Remove all items from the cache.
-func (s *MemoryStore) Flush() error {
- s.mu.RLock()
- defer s.mu.RUnlock()
-
- s.items = map[string]item{}
-
- return nil
-}
-
-func (s *MemoryStore) Tags(names ...string) Store {
- // tags not be supported
- return s
-}
-
-func (s *MemoryStore) TTL(key string) (int64, error) {
- s.mu.RLock()
- defer s.mu.RUnlock()
-
- item, ok := s.items[s.prefix+key]
- if !ok {
- return 0, errors.New("not found")
- }
-
- if item.Expired() {
- return 0, errors.New("not found")
- }
-
- return item.Expiration - time.Now().UnixNano(), nil
-}
-
-// GetPrefix Get the cache key prefix.
-func (s *MemoryStore) GetPrefix() string {
- return s.prefix
-}
-
-// SetPrefix Set the cache key prefix.
-func (s *MemoryStore) SetPrefix(prefix string) *MemoryStore {
- if len(prefix) != 0 {
- s.prefix = fmt.Sprintf("%s:", prefix)
- } else {
- s.prefix = ""
- }
- return s
-}
-
-// Delete all expired items from the cache.
-func (s *MemoryStore) DeleteExpired() {
- s.mu.RLock()
- defer s.mu.RUnlock()
-
- if s.cleanupTimer != nil {
- s.cleanupTimer.Stop()
- }
-
- smallestDuration := 0 * time.Nanosecond
- for key, item := range s.items {
- if item.Expiration < 0 {
- continue
- }
- // "Inlining" of expired
- if item.Expired() {
- delete(s.items, key)
- } else {
- // Find the item chronologically closest to its end-of-lifespan.
- sub := item.Expiration - time.Now().UnixNano()
-
- if smallestDuration == 0 {
- smallestDuration = time.Duration(sub) * time.Nanosecond
- } else {
- if time.Duration(sub)*time.Nanosecond < smallestDuration {
- smallestDuration = time.Duration(sub) * time.Nanosecond
- }
- }
- }
- }
-
- if smallestDuration > 0 {
- s.cleanupTimer = time.AfterFunc(smallestDuration, func() {
- go s.DeleteExpired()
- })
- }
-}
diff --git a/cache/memory_store_test.go b/cache/memory_store_test.go
deleted file mode 100644
index af1fb87..0000000
--- a/cache/memory_store_test.go
+++ /dev/null
@@ -1,131 +0,0 @@
-package cache
-
-import (
- "errors"
- "testing"
- "time"
-)
-
-type CacheUser struct {
- Name string
- Age int
-}
-
-func getMemoryStore() *MemoryStore {
- return NewMemoryStore("cache")
-}
-
-func TestMemoryStore(t *testing.T) {
- s := getMemoryStore()
- var a int
- var b string
- var c CacheUser
-
- err := s.Get("a", &a)
- if err == nil {
- t.Error("Getting A found value that shouldn't exist:", a)
- }
-
- err = s.Get("b", &b)
- if err == nil {
- t.Error("Getting B found value that shouldn't exist:", b)
- }
-
- s.Put("a", 1, 10*time.Minute)
- s.Put("b", "thinkgo", 2*time.Minute)
-
- err = s.Get("a", &a)
- if err != nil {
- t.Error(err)
- }
-
- if a != 1 {
- t.Error("Expect: ", 1)
- }
-
- err = s.Get("b", &b)
- if err != nil {
- t.Error(err)
- }
-
- if b != "thinkgo" {
- t.Error("Expect: ", "thinkgo")
- }
-
- err = s.Put(
- "user", CacheUser{
- Name: "alice",
- Age: 16,
- },
- 10*time.Minute,
- )
- if err != nil {
- t.Error(err)
- }
-
- err = s.Get("user", &c)
- if err != nil {
- t.Error(err)
- }
-
- t.Logf("user:name=%s,age=%d", c.Name, c.Age)
-}
-
-func TestMemoryStoreDuration(t *testing.T) {
- s := getMemoryStore()
- var a int
-
- s.Put("a", 3, 20*time.Millisecond)
-
- <-time.After(21 * time.Millisecond)
- err := s.Get("a", &a)
- if err == nil {
- t.Error("Found a when it should have been automatically deleted")
- }
-}
-
-func TestMemoryStoreForgetAndExist(t *testing.T) {
- s := getMemoryStore()
- err := s.Put("forget", "Forget me", 10*time.Minute)
- if err != nil {
- t.Error(err)
- }
-
- exist := s.Exist("forget")
- if exist != true {
- t.Error(errors.New("Expect true"))
- }
-
- err = s.Forget("forget")
- if err != nil {
- t.Error(err)
- }
-
- exist = s.Exist("forget")
- if exist == true {
- t.Error(errors.New("Expect false"))
- }
-}
-
-func TestMemoryStoreFlush(t *testing.T) {
- s := getMemoryStore()
- err := s.Put("Flush", "Flush all", 10*time.Minute)
- if err != nil {
- t.Error(err)
- }
-
- exist := s.Exist("Flush")
- if exist != true {
- t.Error(errors.New("Expect true"))
- }
-
- err = s.Flush()
- if err != nil {
- t.Error(err)
- }
-
- exist = s.Exist("Flush")
- if exist == true {
- t.Error(errors.New("Expect false"))
- }
-}
diff --git a/cache/redis_store.go b/cache/redis_store.go
deleted file mode 100644
index 9e5fc3c..0000000
--- a/cache/redis_store.go
+++ /dev/null
@@ -1,349 +0,0 @@
-package cache
-
-import (
- "encoding/json"
- "fmt"
- "strings"
- "time"
-
- "github.com/gomodule/redigo/redis"
-)
-
-// ReferenceKeyForever Forever reference key.
-const ReferenceKeyForever = "forever_ref"
-
-// ReferenceKeyStandard Standard reference key.
-const ReferenceKeyStandard = "standard_ref"
-
-type RedisStore struct {
- pool *redis.Pool // redis connection pool
- tagSet *TagSet
- prefix string
-}
-
-// NewRedisStore Create a redis cache store
-func NewRedisStore(pool *redis.Pool, prefix string) *RedisStore {
- s := RedisStore{}
- return s.SetPool(pool).SetPrefix(prefix)
-}
-
-// Get get cached value by key.
-func (s *RedisStore) Get(key string, val interface{}) error {
- c := s.pool.Get()
- defer c.Close()
-
- b, err := redis.Bytes(c.Do("GET", s.prefix+key))
- if err != nil {
- return err
- }
-
- return json.Unmarshal(b, val)
-}
-
-// Put set cached value with key and expire time.
-func (s *RedisStore) Put(key string, val interface{}, timeout time.Duration) error {
- b, err := json.Marshal(val)
- if err != nil {
- return err
- }
-
- err = s.pushStandardKeys(key)
- if err != nil {
- return err
- }
-
- c := s.pool.Get()
- defer c.Close()
- _, err = c.Do("SETEX", s.prefix+key, int64(timeout/time.Second), string(b))
- return err
-}
-
-// Increment the value of an item in the cache.
-func (s *RedisStore) Increment(key string, value ...int) (int, error) {
- err := s.pushStandardKeys(key)
- if err != nil {
- return 0, err
- }
-
- c := s.pool.Get()
- defer c.Close()
-
- var by = 1
- if len(value) > 0 {
- by = value[0]
- }
-
- return redis.Int(c.Do("INCRBY", s.prefix+key, by))
-}
-
-// Decrement the value of an item in the cache.
-func (s *RedisStore) Decrement(key string, value ...int) (int, error) {
- err := s.pushStandardKeys(key)
- if err != nil {
- return 0, err
- }
-
- c := s.pool.Get()
- defer c.Close()
-
- var by = 1
- if len(value) > 0 {
- by = value[0]
- }
-
- return redis.Int(c.Do("DECRBY", s.prefix+key, by))
-}
-
-// Forever Store an item in the cache indefinitely.
-func (s *RedisStore) Forever(key string, val interface{}) error {
- b, err := json.Marshal(val)
- if err != nil {
- return err
- }
-
- err = s.pushForeverKeys(key)
- if err != nil {
- return err
- }
-
- c := s.pool.Get()
- defer c.Close()
- _, err = c.Do("SET", s.prefix+key, string(b))
- return err
-}
-
-// Exist check cache's existence in redis.
-func (s *RedisStore) Exist(key string) bool {
- c := s.pool.Get()
- defer c.Close()
- v, err := redis.Bool(c.Do("EXISTS", s.prefix+key))
- if err != nil {
- return false
- }
- return v
-}
-
-// Expire set value expire time.
-func (s *RedisStore) Expire(key string, timeout time.Duration) error {
- c := s.pool.Get()
- defer c.Close()
- _, err := c.Do("EXPIRE", s.prefix+key, int64(timeout/time.Second))
-
- return err
-}
-
-// Forget Remove an item from the cache.
-func (s *RedisStore) Forget(key string) error {
- c := s.pool.Get()
- defer c.Close()
- _, err := c.Do("DEL", s.prefix+key)
- return err
-}
-
-// Remove all items from the cache.
-func (s *RedisStore) Flush() error {
- if s.tagSet != nil {
- err := s.deleteForeverKeys()
- if err != nil {
- return err
- }
- err = s.deleteStandardKeys()
- if err != nil {
- return err
- }
- err = s.tagSet.Reset()
- if err != nil {
- return err
- }
- return nil
- }
-
- return s.FlushByPrefix("")
-}
-
-func (s *RedisStore) FlushByPrefix(prefix string) error {
- c := s.pool.Get()
- defer c.Close()
-
- var err error
- iter := 0
- keys := []string{}
- pattern := s.prefix + prefix + "*"
- for {
- arr, err := redis.Values(c.Do("SCAN", iter, "MATCH", pattern))
- if err != nil {
- return err
- }
-
- iter, _ = redis.Int(arr[0], nil)
- k, _ := redis.Strings(arr[1], nil)
- keys = append(keys, k...)
-
- if iter == 0 {
- break
- }
- }
-
- length := len(keys)
- if length == 0 {
- return nil
- }
-
- var keysChunk []interface{}
- for i, key := range keys {
- keysChunk = append(keysChunk, key)
- if i == length-1 || len(keysChunk) == 1000 {
- _, err = c.Do("DEL", keysChunk...)
- if err != nil {
- return err
- }
- keysChunk = nil
- }
- }
-
- return nil
-}
-
-func (s *RedisStore) Tags(names ...string) Store {
- if len(names) == 0 {
- return s
- }
- ss := s.clone()
- ss.tagSet = NewTagSet(s, names)
-
- return ss
-}
-
-func (s *RedisStore) TTL(key string) (int64, error) {
- c := s.pool.Get()
- defer c.Close()
-
- return redis.Int64(c.Do("TTL", s.prefix+key))
-}
-
-// SetPool Get the redis pool.
-func (s *RedisStore) SetPool(pool *redis.Pool) *RedisStore {
- s.pool = pool
- return s
-}
-
-// GetPrefix Get the cache key prefix.
-func (s *RedisStore) GetPrefix() string {
- return s.prefix
-}
-
-// SetPrefix Set the cache key prefix.
-func (s *RedisStore) SetPrefix(prefix string) *RedisStore {
- if len(prefix) != 0 {
- s.prefix = fmt.Sprintf("%s:", prefix)
- } else {
- s.prefix = ""
- }
- return s
-}
-
-func (s *RedisStore) clone() *RedisStore {
- return &RedisStore{
- pool: s.pool,
- prefix: s.prefix,
- }
-}
-
-func (s *RedisStore) pushStandardKeys(key string) error {
- return s.pushKeys(key, ReferenceKeyStandard)
-}
-
-func (s *RedisStore) pushForeverKeys(key string) error {
- return s.pushKeys(key, ReferenceKeyForever)
-}
-
-func (s *RedisStore) pushKeys(key, reference string) error {
- if s.tagSet == nil {
- return nil
- }
-
- namespace, err := s.tagSet.GetNamespace()
- if err != nil {
- return err
- }
-
- fullKey := s.prefix + key
- segments := strings.Split(namespace, "|")
-
- c := s.pool.Get()
- defer c.Close()
- for _, segment := range segments {
- _, err = c.Do("SADD", s.referenceKey(segment, reference), fullKey)
- if err != nil {
- return err
- }
- }
- return nil
-}
-
-func (s *RedisStore) deleteStandardKeys() error {
- return s.deleteKeysByReference(ReferenceKeyStandard)
-}
-
-func (s *RedisStore) deleteForeverKeys() error {
- return s.deleteKeysByReference(ReferenceKeyForever)
-}
-
-func (s *RedisStore) deleteKeysByReference(reference string) error {
- if s.tagSet == nil {
- return nil
- }
-
- namespace, err := s.tagSet.GetNamespace()
- if err != nil {
- return err
- }
- segments := strings.Split(namespace, "|")
- c := s.pool.Get()
- defer c.Close()
-
- for _, segment := range segments {
- segment = s.referenceKey(segment, reference)
- err = s.deleteKeys(segment)
- if err != nil {
- return err
- }
- _, err = c.Do("DEL", segment)
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-func (s *RedisStore) deleteKeys(referenceKey string) error {
- c := s.pool.Get()
- defer c.Close()
- keys, err := redis.Strings(c.Do("SMEMBERS", referenceKey))
- if err != nil {
- return err
- }
- var length = len(keys)
- if length == 0 {
- return nil
- }
-
- var keysChunk []interface{}
- for i, key := range keys {
- keysChunk = append(keysChunk, key)
- if i == length-1 || len(keysChunk) == 1000 {
- _, err = c.Do("DEL", keysChunk...)
- if err != nil {
- return err
- }
- keysChunk = nil
- }
- }
-
- return nil
-}
-
-func (s *RedisStore) referenceKey(segment, suffix string) string {
- return s.prefix + segment + ":" + suffix
-}
diff --git a/cache/redis_store_test.go b/cache/redis_store_test.go
deleted file mode 100644
index 49fa084..0000000
--- a/cache/redis_store_test.go
+++ /dev/null
@@ -1,186 +0,0 @@
-package cache
-
-import (
- "errors"
- "testing"
- "time"
-
- "github.com/gomodule/redigo/redis"
-)
-
-func GetPool() *redis.Pool {
- return &redis.Pool{
- MaxIdle: 5,
- MaxActive: 1000,
- IdleTimeout: 300 * time.Second,
- Wait: true,
- // Other pool configuration not shown in this example.
- Dial: func() (redis.Conn, error) {
- c, err := redis.Dial("tcp", "10.0.41.242:6379")
- if err != nil {
- return nil, err
- }
- if _, err := c.Do("AUTH", "abc-123"); err != nil {
- c.Close()
- return nil, err
- }
- if _, err := c.Do("SELECT", 0); err != nil {
- c.Close()
- return nil, err
- }
- return c, nil
- },
- }
-}
-
-func getRedisStore() *RedisStore {
- pool := GetPool()
- return NewRedisStore(pool, "cache")
-}
-
-func TestRedisStoreInt(t *testing.T) {
- s := getRedisStore()
- err := s.Put("int", 9811, 10*time.Minute)
- if err != nil {
- t.Error(err)
- }
-
- var v int
-
- err = s.Get("int", &v)
- if err != nil {
- t.Error(err)
- }
-
- t.Logf("int:%d", v)
-}
-
-func TestRedisStoreString(t *testing.T) {
- s := getRedisStore()
- err := s.Put("str", "this is a string", 10*time.Minute)
- if err != nil {
- t.Error(err)
- }
-
- var str string
-
- err = s.Get("str", &str)
- if err != nil {
- t.Error(err)
- }
-
- t.Logf("str:%s", str)
-}
-
-func TestStoreStruct(t *testing.T) {
- s := getRedisStore()
- err := s.Put(
- "user", CacheUser{
- Name: "alice",
- Age: 16,
- },
- 10*time.Minute,
- )
- if err != nil {
- t.Error(err)
- }
-
- user := &CacheUser{}
-
- err = s.Get("user", user)
- if err != nil {
- t.Error(err)
- }
-
- t.Logf("user:name=%s,age=%d", user.Name, user.Age)
-}
-
-func TestRedisStoreForgetAndExist(t *testing.T) {
- s := getRedisStore()
- err := s.Put("forget", "Forget me", 10*time.Minute)
- if err != nil {
- t.Error(err)
- }
-
- exist := s.Exist("forget")
- if exist != true {
- t.Error(errors.New("Expect true"))
- }
-
- err = s.Forget("forget")
- if err != nil {
- t.Error(err)
- }
-
- exist = s.Exist("forget")
- if exist == true {
- t.Error(errors.New("Expect false"))
- }
-}
-
-func TestRedisStoreFlush(t *testing.T) {
- s := getRedisStore()
- err := s.Put("Flush", "Flush all", 10*time.Minute)
- if err != nil {
- t.Error(err)
- }
-
- exist := s.Exist("Flush")
- if exist != true {
- t.Error(errors.New("Expect true"))
- }
-
- err = s.Flush()
- if err != nil {
- t.Error(err)
- }
-
- exist = s.Exist("Flush")
- if exist == true {
- t.Error(errors.New("Expect false"))
- }
-}
-
-func TestRedisStore_Tags(t *testing.T) {
- cache := getRedisStore()
- key := "john"
- value := "LosAngeles"
- err := cache.Tags("people", "artists").Put(key, value, time.Hour)
- if err != nil {
- t.Fatal(err)
- }
- var val1 string
- cache.Get(key, &val1)
- if value != val1 {
- t.Errorf("%s != %s", value, val1)
- }
-
- var val2 string
- cache.Tags("people").Get(key, &val2)
- if value != val2 {
- t.Errorf("%s != %s", value, val2)
- }
-
- var val3 string
- cache.Tags("artists").Get(key, &val3)
- if value != val3 {
- t.Errorf("%s != %s", value, val3)
- }
-
- cache.Tags("people").Put("bob", "NewYork", time.Hour)
-
- err = cache.Tags("artists").Flush()
- if err != nil {
- t.Fatal(err)
- }
-
- err = cache.Tags("artists").Get(key, &val1)
- if err == nil {
- t.Fatal("err should not be nil")
- }
-
- cache.Tags("people").Get("bob", &val2)
- if "NewYork" != val2 {
- t.Errorf("%s != %s", "NewYork", val2)
- }
-}
diff --git a/cache/repository.go b/cache/repository.go
deleted file mode 100644
index 030639f..0000000
--- a/cache/repository.go
+++ /dev/null
@@ -1,119 +0,0 @@
-package cache
-
-import (
- "time"
-
- "errors"
-)
-
-type Repository struct {
- store Store
-}
-
-func NewRepository(store Store) *Repository {
- s := &Repository{
- store: store,
- }
- return s
-}
-
-// Has Determine if an item exists in the cache.
-func (r *Repository) Has(key string) bool {
- return r.store.Exist(key)
-}
-
-// Get Retrieve an item from the cache by key.
-func (r *Repository) Get(key string, val interface{}) error {
- err := r.store.Get(key, val)
- return err
-}
-
-// Pull Retrieve an item from the cache and delete it.
-func (r *Repository) Pull(key string, val interface{}) error {
- err := r.store.Get(key, val)
- if err != nil {
- return err
- }
- r.store.Forget(key)
- return nil
-}
-
-// Put Store an item in the cache.
-func (r *Repository) Put(key string, val interface{}, timeout time.Duration) error {
- return r.store.Put(key, val, timeout)
-}
-
-// Set Store an item in the cache.
-func (r *Repository) Set(key string, val interface{}, timeout time.Duration) error {
- return r.Put(key, val, timeout)
-}
-
-// Add Store an item in the cache if the key does not exist.
-func (r *Repository) Add(key string, val interface{}, timeout time.Duration) error {
- if r.store.Exist(key) {
- return errors.New("the key already exists:" + key)
- }
- return r.store.Put(key, val, timeout)
-}
-
-// Increment the value of an item in the cache.
-func (r *Repository) Increment(key string, value ...int) (int, error) {
- return r.store.Increment(key, value...)
-}
-
-// Decrement the value of an item in the cache.
-func (r *Repository) Decrement(key string, value ...int) (int, error) {
- return r.store.Decrement(key, value...)
-}
-
-// Expire set value expire time.
-func (r *Repository) Expire(key string, timeout time.Duration) error {
- return r.store.Expire(key, timeout)
-}
-
-// Remember Get an item from the cache, or store the default value.
-func (r *Repository) Remember(key string, val interface{}, timeout time.Duration, callback func() interface{}) error {
- err := r.Get(key, val)
- if err == nil {
- return nil
- }
-
- value := callback()
- if err, ok := value.(error); ok {
- return err
- }
-
- r.Put(key, value, timeout)
-
- return r.Get(key, val)
-}
-
-// Forget Remove an item from the cache.
-func (r *Repository) Forget(key string) error {
- return r.store.Forget(key)
-}
-
-// Delete Alias for the "Delete" method.
-func (r *Repository) Delete(key string) error {
- return r.Forget(key)
-}
-
-// Clear Remove all items from the cache.
-func (r *Repository) Clear() error {
- return r.store.Flush()
-}
-
-// Tags Begin executing a new tags operation if the store supports it.
-func (r *Repository) Tags(names ...string) *Repository {
- return NewRepository(r.store.Tags(names...))
-}
-
-// TTL get the ttl of the key.
-func (r *Repository) TTL(key string) (int64, error) {
- return r.store.TTL(key)
-}
-
-// GetStore Get the cache store implementation.
-func (r *Repository) GetStore() Store {
- return r.store
-}
diff --git a/cache/store.go b/cache/store.go
deleted file mode 100644
index ecc31ac..0000000
--- a/cache/store.go
+++ /dev/null
@@ -1,39 +0,0 @@
-package cache
-
-import (
- "time"
-)
-
-type Store interface {
- // Get get cached value by key.
- Get(key string, val interface{}) error
-
- // Put set cached value with key and expire time.
- Put(key string, val interface{}, timeout time.Duration) error
-
- // Increment the value of an item in the cache.
- Increment(key string, value ...int) (int, error)
-
- // Decrement the value of an item in the cache.
- Decrement(key string, value ...int) (int, error)
-
- // Forever Store an item in the cache indefinitely.
- Forever(key string, val interface{}) error
-
- // Exist check cache's existence in redis.
- Exist(key string) bool
-
- // Expire set value expire time.
- Expire(key string, timeout time.Duration) error
-
- // Forget Remove an item from the cache.
- Forget(key string) error
-
- // Flush Remove all items from the cache.
- Flush() error
-
- Tags(names ...string) Store
-
- // TTL get the ttl of the key.
- TTL(key string) (int64, error)
-}
diff --git a/cache/tag_set.go b/cache/tag_set.go
deleted file mode 100644
index 6a1ae5b..0000000
--- a/cache/tag_set.go
+++ /dev/null
@@ -1,61 +0,0 @@
-package cache
-
-import (
- "strings"
-)
-
-type TagSet struct {
- names []string
- store Store
-}
-
-func NewTagSet(store Store, names []string) *TagSet {
- return &TagSet{names: names, store: store}
-}
-
-func (t *TagSet) Reset() error {
- for _, name := range t.names {
- _, err := t.ResetTag(name)
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-func (t *TagSet) ResetTag(name string) (string, error) {
- id := Sha1(name)
-
- err := t.store.Forever(t.TagKey(name), id)
-
- return id, err
-}
-
-func (t *TagSet) GetNamespace() (string, error) {
- var err error
- var names = make([]string, len(t.names))
- for i, name := range t.names {
- name, err = t.TagId(name)
- if err != nil {
- return "", err
- }
- names[i] = name
- }
- return strings.Join(names, "|"), nil
-}
-
-func (t *TagSet) TagId(name string) (string, error) {
- var id string
- tagKey := t.TagKey(name)
- err := t.store.Get(tagKey, &id)
- if err != nil {
- return t.ResetTag(name)
- }
-
- return id, nil
-}
-
-func (t *TagSet) TagKey(name string) string {
- return "tag:" + name + ":key"
-}
diff --git a/cache/utils.go b/cache/utils.go
deleted file mode 100644
index 79f4bb6..0000000
--- a/cache/utils.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package cache
-
-import (
- "crypto/sha1"
- "fmt"
-)
-
-// Sha1 Calculate the sha1 hash of a string
-func Sha1(str string) string {
- h := sha1.New()
- _, _ = h.Write([]byte(str))
- return fmt.Sprintf("%x", h.Sum(nil))
-}
diff --git a/context/cookie.go b/context/cookie.go
index 46c5490..104ade2 100644
--- a/context/cookie.go
+++ b/context/cookie.go
@@ -6,7 +6,7 @@ import (
"net/url"
"time"
- "github.com/forgoer/thinkgo/config"
+ "github.com/go-think/think/config"
)
type CookieConfig struct {
diff --git a/contract/log.go b/contract/log.go
new file mode 100644
index 0000000..a257510
--- /dev/null
+++ b/contract/log.go
@@ -0,0 +1,20 @@
+package contract
+
+type Logger interface {
+ // Debug Adds a log record at the DEBUG level.
+ Debug(v string, args ...interface{})
+ // Info Adds a log record at the INFO level.
+ Info(v string, args ...interface{})
+ // Notice Adds a log record at the NOTICE level.
+ Notice(v string, args ...interface{})
+ // Warn Adds a log record at the WARNING level.
+ Warn(v string, args ...interface{})
+ // Error Adds a log record at the ERROR level.
+ Error(v string, args ...interface{})
+ // Crit Adds a log record at the CRITICAL level.
+ Crit(v string, args ...interface{})
+ // Alert Adds a log record at the ALERT level.
+ Alert(v string, args ...interface{})
+ // Emerg Adds a log record at the EMERGENCY level.
+ Emerg(v string, args ...interface{})
+}
diff --git a/covprofile b/covprofile
new file mode 100644
index 0000000..d4b7359
--- /dev/null
+++ b/covprofile
@@ -0,0 +1,483 @@
+mode: atomic
+github.com/go-think/think/view/view.go:16.18,19.2 2 2
+github.com/go-think/think/view/view.go:23.42,25.2 1 1
+github.com/go-think/think/view/view.go:27.68,29.17 2 2
+github.com/go-think/think/view/view.go:29.17,33.3 3 1
+github.com/go-think/think/view/view.go:34.2,37.36 3 2
+github.com/go-think/think/view/view.go:40.58,42.2 1 0
+github.com/go-think/think/view/view.go:44.32,46.2 1 0
+github.com/go-think/think/helper/helper.go:11.41,13.9 2 0
+github.com/go-think/think/helper/helper.go:13.9,14.54 1 0
+github.com/go-think/think/helper/helper.go:17.2,19.20 2 0
+github.com/go-think/think/helper/helper.go:19.20,21.3 1 0
+github.com/go-think/think/helper/helper.go:23.2,23.12 1 0
+github.com/go-think/think/helper/helper.go:26.38,28.16 2 0
+github.com/go-think/think/helper/helper.go:28.16,29.13 1 0
+github.com/go-think/think/helper/helper.go:32.2,32.20 1 0
+github.com/go-think/think/helper/helper.go:32.20,34.3 1 0
+github.com/go-think/think/helper/helper.go:36.2,36.12 1 0
+github.com/go-think/think/helper/helper.go:39.37,43.20 2 0
+github.com/go-think/think/helper/helper.go:43.20,45.3 1 0
+github.com/go-think/think/helper/helper.go:47.2,47.12 1 0
+github.com/go-think/think/helper/helper.go:50.40,53.20 2 0
+github.com/go-think/think/helper/helper.go:53.20,55.3 1 0
+github.com/go-think/think/helper/helper.go:57.2,57.12 1 0
+github.com/go-think/think/helper/utils.go:8.40,11.20 3 0
+github.com/go-think/think/helper/utils.go:12.9,13.46 1 0
+github.com/go-think/think/helper/utils.go:13.46,15.4 1 0
+github.com/go-think/think/helper/utils.go:16.3,16.46 1 0
+github.com/go-think/think/helper/utils.go:16.46,18.4 1 0
+github.com/go-think/think/helper/utils.go:19.9,21.37 2 0
+github.com/go-think/think/helper/utils.go:21.37,23.4 1 0
+github.com/go-think/think/helper/utils.go:24.3,24.37 1 0
+github.com/go-think/think/helper/utils.go:24.37,26.4 1 0
+github.com/go-think/think/helper/utils.go:27.10,27.10 0 0
+github.com/go-think/think/helper/utils.go:30.2,30.26 1 0
+github.com/go-think/think/filesystem/fs.go:14.73,16.19 2 0
+github.com/go-think/think/filesystem/fs.go:16.19,18.3 1 0
+github.com/go-think/think/filesystem/fs.go:19.2,19.31 1 0
+github.com/go-think/think/filesystem/fs.go:22.63,24.16 2 0
+github.com/go-think/think/filesystem/fs.go:24.16,26.3 1 0
+github.com/go-think/think/filesystem/fs.go:27.2,30.8 1 0
+github.com/go-think/think/filesystem/fs.go:38.55,40.16 2 0
+github.com/go-think/think/filesystem/fs.go:40.16,42.3 1 0
+github.com/go-think/think/filesystem/fs.go:43.2,43.15 1 0
+github.com/go-think/think/filesystem/fs.go:43.15,45.7 1 0
+github.com/go-think/think/filesystem/fs.go:45.7,47.15 2 0
+github.com/go-think/think/filesystem/fs.go:48.16,49.15 1 0
+github.com/go-think/think/filesystem/fs.go:50.13,51.26 1 0
+github.com/go-think/think/filesystem/fs.go:51.26,52.34 1 0
+github.com/go-think/think/filesystem/fs.go:52.34,54.7 1 0
+github.com/go-think/think/filesystem/fs.go:56.12,57.20 1 0
+github.com/go-think/think/filesystem/fs.go:60.3,60.29 1 0
+github.com/go-think/think/filesystem/fs.go:62.2,62.15 1 0
+github.com/go-think/think/filesystem/utils.go:14.40,16.16 2 0
+github.com/go-think/think/filesystem/utils.go:16.16,18.3 1 0
+github.com/go-think/think/filesystem/utils.go:19.2,19.24 1 0
+github.com/go-think/think/filesystem/utils.go:19.24,21.3 1 0
+github.com/go-think/think/filesystem/utils.go:22.2,22.19 1 0
+github.com/go-think/think/filesystem/utils.go:25.39,34.16 6 0
+github.com/go-think/think/filesystem/utils.go:34.16,36.3 1 0
+github.com/go-think/think/filesystem/utils.go:38.2,39.16 2 0
+github.com/go-think/think/filesystem/utils.go:39.16,41.3 1 0
+github.com/go-think/think/filesystem/utils.go:42.2,42.15 1 0
+github.com/go-think/think/filesystem/utils.go:45.42,50.31 4 0
+github.com/go-think/think/filesystem/utils.go:50.31,52.17 2 0
+github.com/go-think/think/filesystem/utils.go:52.17,54.4 1 0
+github.com/go-think/think/filesystem/utils.go:57.2,60.16 3 0
+github.com/go-think/think/filesystem/utils.go:60.16,62.3 1 0
+github.com/go-think/think/filesystem/utils.go:63.2,64.12 2 0
+github.com/go-think/think/filesystem/utils.go:67.46,70.16 3 0
+github.com/go-think/think/filesystem/utils.go:70.16,72.3 1 0
+github.com/go-think/think/filesystem/utils.go:73.2,73.32 1 0
+github.com/go-think/think/context/cookie.go:34.85,37.21 2 0
+github.com/go-think/think/context/cookie.go:38.20,39.31 1 0
+github.com/go-think/think/context/cookie.go:40.14,41.23 1 0
+github.com/go-think/think/context/cookie.go:41.23,43.4 1 0
+github.com/go-think/think/context/cookie.go:45.3,46.35 2 0
+github.com/go-think/think/context/cookie.go:46.35,48.4 1 0
+github.com/go-think/think/context/cookie.go:49.3,60.22 2 0
+github.com/go-think/think/context/cookie.go:60.22,62.34 2 0
+github.com/go-think/think/context/cookie.go:62.34,64.5 1 0
+github.com/go-think/think/context/cookie.go:65.4,65.32 1 0
+github.com/go-think/think/context/cookie.go:68.3,68.22 1 0
+github.com/go-think/think/context/cookie.go:68.22,70.35 2 0
+github.com/go-think/think/context/cookie.go:70.35,72.5 1 0
+github.com/go-think/think/context/cookie.go:73.4,73.31 1 0
+github.com/go-think/think/context/cookie.go:76.3,76.22 1 0
+github.com/go-think/think/context/cookie.go:76.22,78.37 2 0
+github.com/go-think/think/context/cookie.go:78.37,80.5 1 0
+github.com/go-think/think/context/cookie.go:81.4,81.35 1 0
+github.com/go-think/think/context/cookie.go:84.3,84.22 1 0
+github.com/go-think/think/context/cookie.go:84.22,86.35 2 0
+github.com/go-think/think/context/cookie.go:86.35,88.5 1 0
+github.com/go-think/think/context/cookie.go:89.4,89.33 1 0
+github.com/go-think/think/context/cookie.go:91.10,92.59 1 0
+github.com/go-think/think/context/cookie.go:94.2,94.20 1 0
+github.com/go-think/think/context/cookie.go:97.35,109.2 1 0
+github.com/go-think/think/context/file.go:14.69,16.16 2 0
+github.com/go-think/think/context/file.go:16.16,18.3 1 0
+github.com/go-think/think/context/file.go:19.2,23.19 3 0
+github.com/go-think/think/context/file.go:23.19,25.3 1 0
+github.com/go-think/think/context/file.go:27.2,30.16 3 0
+github.com/go-think/think/context/file.go:30.16,32.3 1 0
+github.com/go-think/think/context/file.go:33.2,37.18 3 0
+github.com/go-think/think/context/request.go:25.45,34.2 1 0
+github.com/go-think/think/context/request.go:37.38,39.2 1 0
+github.com/go-think/think/context/request.go:42.36,44.2 1 0
+github.com/go-think/think/context/request.go:47.50,49.2 1 0
+github.com/go-think/think/context/request.go:52.43,54.2 1 0
+github.com/go-think/think/context/request.go:57.70,58.31 1 0
+github.com/go-think/think/context/request.go:58.31,60.3 1 0
+github.com/go-think/think/context/request.go:61.2,61.20 1 0
+github.com/go-think/think/context/request.go:61.20,63.3 1 0
+github.com/go-think/think/context/request.go:64.2,64.50 1 0
+github.com/go-think/think/context/request.go:68.70,69.30 1 0
+github.com/go-think/think/context/request.go:69.30,71.3 1 0
+github.com/go-think/think/context/request.go:73.2,73.31 1 0
+github.com/go-think/think/context/request.go:73.31,75.3 1 0
+github.com/go-think/think/context/request.go:77.2,77.20 1 0
+github.com/go-think/think/context/request.go:77.20,79.3 1 0
+github.com/go-think/think/context/request.go:80.2,80.50 1 0
+github.com/go-think/think/context/request.go:84.69,85.30 1 0
+github.com/go-think/think/context/request.go:85.30,87.3 1 0
+github.com/go-think/think/context/request.go:89.2,89.20 1 0
+github.com/go-think/think/context/request.go:89.20,91.3 1 0
+github.com/go-think/think/context/request.go:92.2,92.49 1 0
+github.com/go-think/think/context/request.go:96.71,100.16 4 0
+github.com/go-think/think/context/request.go:100.16,103.3 2 0
+github.com/go-think/think/context/request.go:104.2,104.20 1 0
+github.com/go-think/think/context/request.go:104.20,106.3 1 0
+github.com/go-think/think/context/request.go:107.2,107.16 1 0
+github.com/go-think/think/context/request.go:111.51,112.31 1 0
+github.com/go-think/think/context/request.go:112.31,114.3 1 0
+github.com/go-think/think/context/request.go:116.2,117.16 2 0
+github.com/go-think/think/context/request.go:117.16,119.3 1 0
+github.com/go-think/think/context/request.go:120.2,122.26 2 0
+github.com/go-think/think/context/request.go:126.56,128.16 2 0
+github.com/go-think/think/context/request.go:128.16,130.3 1 0
+github.com/go-think/think/context/request.go:131.2,131.75 1 0
+github.com/go-think/think/context/request.go:131.75,132.53 1 0
+github.com/go-think/think/context/request.go:132.53,134.4 1 0
+github.com/go-think/think/context/request.go:136.2,136.21 1 0
+github.com/go-think/think/context/request.go:140.57,143.20 2 0
+github.com/go-think/think/context/request.go:143.20,145.3 1 0
+github.com/go-think/think/context/request.go:147.2,149.27 2 0
+github.com/go-think/think/context/request.go:149.27,150.28 1 0
+github.com/go-think/think/context/request.go:150.28,152.4 1 0
+github.com/go-think/think/context/request.go:152.9,154.4 1 0
+github.com/go-think/think/context/request.go:157.2,157.15 1 0
+github.com/go-think/think/context/request.go:161.58,166.27 3 0
+github.com/go-think/think/context/request.go:166.27,167.28 1 0
+github.com/go-think/think/context/request.go:167.28,169.4 1 0
+github.com/go-think/think/context/request.go:172.2,172.15 1 0
+github.com/go-think/think/context/request.go:176.60,179.27 2 0
+github.com/go-think/think/context/request.go:179.27,180.28 1 0
+github.com/go-think/think/context/request.go:180.28,182.4 1 0
+github.com/go-think/think/context/request.go:185.2,185.12 1 0
+github.com/go-think/think/context/request.go:189.47,192.27 2 0
+github.com/go-think/think/context/request.go:192.27,193.29 1 0
+github.com/go-think/think/context/request.go:193.29,195.4 1 0
+github.com/go-think/think/context/request.go:198.2,198.13 1 0
+github.com/go-think/think/context/request.go:202.44,205.27 2 0
+github.com/go-think/think/context/request.go:205.27,206.29 1 0
+github.com/go-think/think/context/request.go:206.29,208.4 1 0
+github.com/go-think/think/context/request.go:209.3,209.25 1 0
+github.com/go-think/think/context/request.go:209.25,211.4 1 0
+github.com/go-think/think/context/request.go:214.2,214.13 1 0
+github.com/go-think/think/context/request.go:218.32,220.2 1 0
+github.com/go-think/think/context/request.go:223.36,225.2 1 0
+github.com/go-think/think/context/request.go:228.33,230.2 1 0
+github.com/go-think/think/context/request.go:233.35,235.2 1 0
+github.com/go-think/think/context/request.go:238.48,241.17 2 0
+github.com/go-think/think/context/request.go:241.17,243.17 2 0
+github.com/go-think/think/context/request.go:243.17,245.4 1 0
+github.com/go-think/think/context/request.go:246.3,246.59 1 0
+github.com/go-think/think/context/request.go:249.2,249.18 1 0
+github.com/go-think/think/context/request.go:253.37,255.2 1 0
+github.com/go-think/think/context/request.go:258.41,260.2 1 0
+github.com/go-think/think/context/request.go:262.49,264.22 2 0
+github.com/go-think/think/context/request.go:264.22,266.3 1 0
+github.com/go-think/think/context/request.go:267.2,267.14 1 0
+github.com/go-think/think/context/request.go:270.51,274.31 3 0
+github.com/go-think/think/context/request.go:274.31,276.3 1 0
+github.com/go-think/think/context/request.go:278.2,279.28 2 0
+github.com/go-think/think/context/request.go:279.28,280.43 1 0
+github.com/go-think/think/context/request.go:280.43,282.4 1 0
+github.com/go-think/think/context/request.go:285.2,285.13 1 0
+github.com/go-think/think/context/request.go:288.63,291.31 2 0
+github.com/go-think/think/context/request.go:291.31,292.27 1 0
+github.com/go-think/think/context/request.go:292.27,294.4 1 0
+github.com/go-think/think/context/request.go:297.2,297.10 1 0
+github.com/go-think/think/context/response.go:19.57,22.2 2 0
+github.com/go-think/think/context/response.go:25.53,28.2 2 0
+github.com/go-think/think/context/response.go:31.47,34.2 2 0
+github.com/go-think/think/context/response.go:37.53,40.2 2 0
+github.com/go-think/think/context/response.go:43.44,45.2 1 0
+github.com/go-think/think/context/response.go:48.40,50.2 1 0
+github.com/go-think/think/context/response.go:53.34,55.2 1 0
+github.com/go-think/think/context/response.go:58.40,60.2 1 0
+github.com/go-think/think/context/response.go:63.74,66.16 2 0
+github.com/go-think/think/context/response.go:66.16,67.23 1 0
+github.com/go-think/think/context/response.go:67.23,69.4 1 0
+github.com/go-think/think/context/response.go:70.3,70.34 1 0
+github.com/go-think/think/context/response.go:73.2,73.12 1 0
+github.com/go-think/think/context/response.go:77.48,78.35 1 0
+github.com/go-think/think/context/response.go:78.35,80.3 1 0
+github.com/go-think/think/context/response.go:81.2,81.36 1 0
+github.com/go-think/think/context/response.go:81.36,82.29 1 0
+github.com/go-think/think/context/response.go:82.29,84.4 1 0
+github.com/go-think/think/context/response.go:86.2,89.33 3 0
+github.com/go-think/think/context/response.go:93.30,102.2 6 0
+github.com/go-think/think/context/response.go:105.35,107.2 1 0
+github.com/go-think/think/context/response.go:110.32,112.2 1 0
+github.com/go-think/think/context/response.go:115.36,119.2 3 0
+github.com/go-think/think/session/cookie-handler.go:8.40,10.2 1 0
+github.com/go-think/think/session/cookie-handler.go:12.49,14.2 1 0
+github.com/go-think/think/session/cookie-handler.go:16.51,18.2 1 0
+github.com/go-think/think/session/cookie-handler.go:20.48,24.2 2 0
+github.com/go-think/think/session/cookie-handler.go:26.55,28.2 1 0
+github.com/go-think/think/session/file-handler.go:15.46,19.46 2 0
+github.com/go-think/think/session/file-handler.go:19.46,21.49 2 0
+github.com/go-think/think/session/file-handler.go:21.49,23.18 2 0
+github.com/go-think/think/session/file-handler.go:23.18,24.15 1 0
+github.com/go-think/think/session/file-handler.go:26.4,26.23 1 0
+github.com/go-think/think/session/file-handler.go:29.2,29.11 1 0
+github.com/go-think/think/session/file-handler.go:32.53,37.16 3 0
+github.com/go-think/think/session/file-handler.go:37.16,38.13 1 0
+github.com/go-think/think/session/manager.go:30.42,36.2 2 0
+github.com/go-think/think/session/manager.go:38.52,41.48 2 0
+github.com/go-think/think/session/manager.go:41.48,43.3 1 0
+github.com/go-think/think/session/manager.go:44.2,47.16 4 0
+github.com/go-think/think/session/manager.go:50.52,51.48 1 0
+github.com/go-think/think/session/manager.go:51.48,53.3 1 0
+github.com/go-think/think/session/manager.go:54.2,56.16 3 0
+github.com/go-think/think/session/manager.go:59.45,60.27 1 0
+github.com/go-think/think/session/manager.go:60.27,62.3 1 0
+github.com/go-think/think/session/manager.go:63.2,63.34 1 0
+github.com/go-think/think/session/manager.go:66.56,69.2 2 0
+github.com/go-think/think/session/manager.go:71.75,74.2 2 0
+github.com/go-think/think/session/manager.go:76.32,77.20 1 0
+github.com/go-think/think/session/manager.go:77.20,79.3 1 0
+github.com/go-think/think/session/manager.go:81.2,83.3 1 0
+github.com/go-think/think/session/manager.go:86.47,88.25 2 0
+github.com/go-think/think/session/manager.go:89.16,90.34 1 0
+github.com/go-think/think/session/manager.go:91.14,95.4 1 0
+github.com/go-think/think/session/manager.go:96.10,99.10 3 0
+github.com/go-think/think/session/manager.go:99.10,100.59 1 0
+github.com/go-think/think/session/manager.go:104.2,104.21 1 0
+github.com/go-think/think/session/redis-handler.go:16.93,18.2 1 0
+github.com/go-think/think/session/redis-handler.go:20.48,25.16 4 0
+github.com/go-think/think/session/redis-handler.go:25.16,27.3 1 0
+github.com/go-think/think/session/redis-handler.go:29.2,33.14 3 0
+github.com/go-think/think/session/redis-handler.go:36.55,41.2 3 0
+github.com/go-think/think/session/store.go:21.52,28.2 2 0
+github.com/go-think/think/session/store.go:30.38,32.2 1 0
+github.com/go-think/think/session/store.go:34.32,36.2 1 0
+github.com/go-think/think/session/store.go:38.34,39.17 1 0
+github.com/go-think/think/session/store.go:39.17,41.3 1 0
+github.com/go-think/think/session/store.go:43.2,43.11 1 0
+github.com/go-think/think/session/store.go:46.34,48.2 1 0
+github.com/go-think/think/session/store.go:50.25,59.26 5 0
+github.com/go-think/think/session/store.go:59.26,61.3 1 0
+github.com/go-think/think/session/store.go:64.68,65.37 1 0
+github.com/go-think/think/session/store.go:65.37,67.3 1 0
+github.com/go-think/think/session/store.go:68.2,68.20 1 0
+github.com/go-think/think/session/store.go:68.20,70.3 1 0
+github.com/go-think/think/session/store.go:71.2,71.12 1 0
+github.com/go-think/think/session/store.go:74.53,76.2 1 0
+github.com/go-think/think/session/store.go:78.46,80.2 1 0
+github.com/go-think/think/session/store.go:82.49,86.2 3 0
+github.com/go-think/think/session/store.go:88.41,89.29 1 0
+github.com/go-think/think/session/store.go:89.29,91.3 1 0
+github.com/go-think/think/session/store.go:94.25,96.2 1 0
+github.com/go-think/think/session/store.go:98.24,103.2 3 0
+github.com/go-think/think/session/store.go:105.33,115.2 7 0
+github.com/go-think/think/config/config.go:13.13,19.2 5 0
+github.com/go-think/think/config/config.go:21.22,27.2 1 0
+github.com/go-think/think/config/config.go:29.24,36.2 1 0
+github.com/go-think/think/config/config.go:38.23,42.2 1 0
+github.com/go-think/think/config/config.go:44.25,54.2 1 0
+github.com/go-think/think/config/config.go:56.26,64.2 1 0
+github.com/go-think/think/router/metch.go:7.46,8.19 1 0
+github.com/go-think/think/router/metch.go:8.19,10.3 1 0
+github.com/go-think/think/router/metch.go:12.2,12.22 1 0
+github.com/go-think/think/router/metch.go:12.22,14.3 1 0
+github.com/go-think/think/router/metch.go:16.2,16.14 1 0
+github.com/go-think/think/router/metch.go:19.56,20.27 1 0
+github.com/go-think/think/router/metch.go:20.27,21.29 1 0
+github.com/go-think/think/router/metch.go:21.29,23.4 1 0
+github.com/go-think/think/router/metch.go:25.2,25.14 1 0
+github.com/go-think/think/router/metch.go:28.42,32.16 2 0
+github.com/go-think/think/router/metch.go:32.16,34.3 1 0
+github.com/go-think/think/router/metch.go:36.2,36.12 1 0
+github.com/go-think/think/router/pipeline.go:16.30,21.2 2 0
+github.com/go-think/think/router/pipeline.go:24.49,27.2 2 0
+github.com/go-think/think/router/pipeline.go:30.56,31.25 1 0
+github.com/go-think/think/router/pipeline.go:31.25,33.3 1 0
+github.com/go-think/think/router/pipeline.go:34.2,34.10 1 0
+github.com/go-think/think/router/pipeline.go:38.66,41.2 2 0
+github.com/go-think/think/router/pipeline.go:44.60,50.14 4 0
+github.com/go-think/think/router/pipeline.go:50.14,52.3 1 0
+github.com/go-think/think/router/pipeline.go:53.2,53.15 1 0
+github.com/go-think/think/router/pipeline.go:56.84,57.14 1 0
+github.com/go-think/think/router/pipeline.go:57.14,59.3 1 0
+github.com/go-think/think/router/pipeline.go:60.2,62.15 3 0
+github.com/go-think/think/router/pipeline.go:65.53,66.48 1 0
+github.com/go-think/think/router/pipeline.go:66.48,69.3 2 0
+github.com/go-think/think/router/route.go:36.19,41.2 2 0
+github.com/go-think/think/router/route.go:44.58,46.16 2 0
+github.com/go-think/think/router/route.go:46.16,48.3 1 0
+github.com/go-think/think/router/route.go:50.2,52.18 2 0
+github.com/go-think/think/router/route.go:56.55,57.52 1 0
+github.com/go-think/think/router/route.go:57.52,58.67 1 0
+github.com/go-think/think/router/route.go:58.67,60.4 1 0
+github.com/go-think/think/router/route.go:62.2,62.37 1 0
+github.com/go-think/think/router/route.go:66.43,69.36 3 0
+github.com/go-think/think/router/route.go:69.36,71.36 1 0
+github.com/go-think/think/router/route.go:71.36,75.4 1 0
+github.com/go-think/think/router/route.go:75.9,77.4 1 0
+github.com/go-think/think/router/route.go:81.2,81.23 1 0
+github.com/go-think/think/router/route.go:81.23,83.3 1 0
+github.com/go-think/think/router/route.go:84.2,86.13 2 0
+github.com/go-think/think/router/route.go:90.82,96.2 5 0
+github.com/go-think/think/router/route.go:99.65,101.2 1 0
+github.com/go-think/think/router/route.go:104.66,106.2 1 0
+github.com/go-think/think/router/route.go:109.66,111.2 1 0
+github.com/go-think/think/router/route.go:114.65,116.2 1 0
+github.com/go-think/think/router/route.go:119.67,121.2 1 0
+github.com/go-think/think/router/route.go:124.68,126.2 1 0
+github.com/go-think/think/router/route.go:129.69,131.2 1 0
+github.com/go-think/think/router/route.go:134.65,136.2 1 0
+github.com/go-think/think/router/route.go:139.43,146.2 4 0
+github.com/go-think/think/router/route.go:149.52,150.34 1 0
+github.com/go-think/think/router/route.go:150.34,152.3 1 0
+github.com/go-think/think/router/route.go:156.46,160.2 3 0
+github.com/go-think/think/router/route.go:163.59,169.2 5 0
+github.com/go-think/think/router/route.go:172.62,174.32 2 0
+github.com/go-think/think/router/route.go:174.32,176.3 1 0
+github.com/go-think/think/router/route.go:177.2,177.14 1 0
+github.com/go-think/think/router/route.go:181.28,183.2 1 0
+github.com/go-think/think/router/route.go:185.31,187.34 2 0
+github.com/go-think/think/router/route.go:187.34,189.3 1 0
+github.com/go-think/think/router/route.go:191.2,191.18 1 0
+github.com/go-think/think/router/route.go:194.39,195.35 1 0
+github.com/go-think/think/router/route.go:195.35,199.35 3 0
+github.com/go-think/think/router/route.go:199.35,201.4 1 0
+github.com/go-think/think/router/route.go:202.3,202.39 1 0
+github.com/go-think/think/router/route.go:202.39,204.4 1 0
+github.com/go-think/think/router/route.go:205.3,209.27 3 0
+github.com/go-think/think/router/route.go:209.27,210.12 1 0
+github.com/go-think/think/router/route.go:212.3,219.21 2 0
+github.com/go-think/think/router/route.go:221.2,221.30 1 0
+github.com/go-think/think/router/route.go:225.36,227.15 2 0
+github.com/go-think/think/router/route.go:227.15,235.3 2 0
+github.com/go-think/think/router/route.go:236.2,236.14 1 0
+github.com/go-think/think/router/route.go:239.37,249.2 3 0
+github.com/go-think/think/router/route.go:251.50,253.2 1 0
+github.com/go-think/think/router/router.go:8.65,14.2 1 0
+github.com/go-think/think/router/router.go:17.92,30.2 1 0
+github.com/go-think/think/router/router.go:33.71,36.49 2 0
+github.com/go-think/think/router/router.go:36.49,38.3 1 0
+github.com/go-think/think/router/router.go:39.2,39.97 1 0
+github.com/go-think/think/router/router.go:39.97,45.3 1 0
+github.com/go-think/think/router/rule.go:27.50,30.45 2 0
+github.com/go-think/think/router/rule.go:30.45,32.3 1 0
+github.com/go-think/think/router/rule.go:34.2,34.48 1 0
+github.com/go-think/think/router/rule.go:34.48,36.3 1 0
+github.com/go-think/think/router/rule.go:38.2,38.13 1 0
+github.com/go-think/think/router/rule.go:42.34,51.30 6 0
+github.com/go-think/think/router/rule.go:51.30,53.3 1 0
+github.com/go-think/think/router/rule.go:55.2,57.35 2 0
+github.com/go-think/think/router/rule.go:57.35,62.3 1 0
+github.com/go-think/think/router/rule.go:64.2,64.27 1 0
+github.com/go-think/think/router/rule.go:68.60,69.32 1 0
+github.com/go-think/think/router/rule.go:69.32,71.3 1 0
+github.com/go-think/think/router/rule.go:72.2,72.10 1 0
+github.com/go-think/think/router/rule.go:76.53,78.2 1 0
+github.com/go-think/think/router/rule.go:81.67,82.22 1 0
+github.com/go-think/think/router/rule.go:82.22,84.3 1 0
+github.com/go-think/think/router/rule.go:86.2,87.25 2 0
+github.com/go-think/think/router/rule.go:88.20,92.19 3 0
+github.com/go-think/think/router/rule.go:92.19,94.4 1 0
+github.com/go-think/think/router/rule.go:95.10,96.21 1 0
+github.com/go-think/think/router/rule.go:99.2,99.8 1 0
+github.com/go-think/think/router/rule.go:103.45,104.29 1 0
+github.com/go-think/think/router/rule.go:104.29,106.3 1 0
+github.com/go-think/think/router/rule.go:107.2,109.25 2 0
+github.com/go-think/think/router/rule.go:112.26,113.23 1 0
+github.com/go-think/think/router/rule.go:113.23,115.3 1 0
+github.com/go-think/think/router/rule.go:117.2,124.3 4 0
+github.com/go-think/think/router/rule.go:127.49,132.28 4 0
+github.com/go-think/think/router/rule.go:132.28,134.3 1 0
+github.com/go-think/think/router/rule.go:136.2,136.15 1 0
+github.com/go-think/think/router/rule.go:139.106,142.17 3 0
+github.com/go-think/think/router/rule.go:142.17,144.3 1 0
+github.com/go-think/think/router/rule.go:146.2,150.9 5 0
+github.com/go-think/think/router/rule.go:150.9,152.3 1 0
+github.com/go-think/think/router/rule.go:153.2,153.49 1 0
+github.com/go-think/think/router/rule.go:153.49,155.10 2 0
+github.com/go-think/think/router/rule.go:155.10,157.4 1 0
+github.com/go-think/think/router/rule.go:157.9,159.4 1 0
+github.com/go-think/think/router/rule.go:160.3,161.12 2 0
+github.com/go-think/think/router/rule.go:164.2,164.31 1 0
+github.com/go-think/think/router/rule.go:164.31,166.3 1 0
+github.com/go-think/think/router/rule.go:168.2,168.11 1 0
+github.com/go-think/think/router/static.go:15.48,21.2 2 0
+github.com/go-think/think/router/static.go:24.74,26.2 1 0
+github.com/go-think/think/router/utils.go:8.40,10.22 2 0
+github.com/go-think/think/router/utils.go:10.22,12.3 1 0
+github.com/go-think/think/router/utils.go:13.2,13.27 1 0
+github.com/go-think/think/router/utils.go:13.27,15.3 1 0
+github.com/go-think/think/router/utils.go:16.2,16.16 1 0
+github.com/go-think/think/app.go:19.36,21.2 1 2
+github.com/go-think/think/app.go:24.54,26.2 1 2
+github.com/go-think/think/app.go:29.50,31.2 1 0
+github.com/go-think/think/app.go:34.48,36.2 1 6
+github.com/go-think/think/app.go:39.44,41.2 1 0
+github.com/go-think/think/pipeline.go:19.30,24.2 2 2
+github.com/go-think/think/pipeline.go:27.46,30.2 2 2
+github.com/go-think/think/pipeline.go:33.53,34.25 1 0
+github.com/go-think/think/pipeline.go:34.25,36.3 1 0
+github.com/go-think/think/pipeline.go:37.2,37.10 1 0
+github.com/go-think/think/pipeline.go:41.66,44.2 2 5
+github.com/go-think/think/pipeline.go:47.38,50.14 3 5
+github.com/go-think/think/pipeline.go:50.14,52.3 1 5
+github.com/go-think/think/pipeline.go:53.2,53.15 1 5
+github.com/go-think/think/pipeline.go:57.70,64.23 5 5
+github.com/go-think/think/pipeline.go:65.23,67.8 2 1
+github.com/go-think/think/pipeline.go:68.21,70.8 2 0
+github.com/go-think/think/pipeline.go:71.20,73.8 2 0
+github.com/go-think/think/pipeline.go:74.10,76.8 2 4
+github.com/go-think/think/pipeline.go:80.84,81.14 1 5
+github.com/go-think/think/pipeline.go:81.14,83.3 1 0
+github.com/go-think/think/pipeline.go:84.2,86.15 3 5
+github.com/go-think/think/pipeline.go:89.53,90.48 1 5
+github.com/go-think/think/pipeline.go:90.48,93.3 2 0
+github.com/go-think/think/recover_handler.go:17.50,21.2 1 0
+github.com/go-think/think/recover_handler.go:24.91,25.15 1 0
+github.com/go-think/think/recover_handler.go:25.15,26.35 1 0
+github.com/go-think/think/recover_handler.go:26.35,28.22 2 0
+github.com/go-think/think/recover_handler.go:28.22,30.13 2 0
+github.com/go-think/think/recover_handler.go:30.13,31.11 1 0
+github.com/go-think/think/recover_handler.go:34.5,34.47 1 0
+github.com/go-think/think/recover_handler.go:37.4,40.37 3 0
+github.com/go-think/think/recover_handler.go:40.37,42.38 2 0
+github.com/go-think/think/recover_handler.go:42.38,44.6 1 0
+github.com/go-think/think/recover_handler.go:47.4,52.19 5 0
+github.com/go-think/think/recover_handler.go:52.19,54.5 1 0
+github.com/go-think/think/recover_handler.go:55.4,55.21 1 0
+github.com/go-think/think/recover_handler.go:59.2,59.18 1 0
+github.com/go-think/think/response.go:13.44,16.2 2 0
+github.com/go-think/think/response.go:19.39,21.2 1 1
+github.com/go-think/think/response.go:24.39,26.2 1 0
+github.com/go-think/think/response.go:28.48,34.18 5 4
+github.com/go-think/think/response.go:35.20,36.33 1 0
+github.com/go-think/think/response.go:37.22,38.33 1 4
+github.com/go-think/think/response.go:40.64,41.33 1 0
+github.com/go-think/think/response.go:42.40,43.33 1 0
+github.com/go-think/think/response.go:44.10,47.17 3 0
+github.com/go-think/think/response.go:47.17,48.154 1 0
+github.com/go-think/think/response.go:50.3,50.22 1 0
+github.com/go-think/think/response.go:52.2,54.10 2 4
+github.com/go-think/think/route_hendler.go:13.48,17.2 1 2
+github.com/go-think/think/route_hendler.go:20.84,23.16 2 5
+github.com/go-think/think/route_hendler.go:23.16,25.3 1 0
+github.com/go-think/think/route_hendler.go:27.2,27.39 1 5
+github.com/go-think/think/session_handler.go:15.50,28.2 4 0
+github.com/go-think/think/session_handler.go:30.82,37.46 4 0
+github.com/go-think/think/session_handler.go:37.46,39.3 1 0
+github.com/go-think/think/session_handler.go:41.2,41.15 1 0
+github.com/go-think/think/session_handler.go:44.76,46.2 1 0
+github.com/go-think/think/session_handler.go:48.60,50.2 1 0
+github.com/go-think/think/think.go:27.19,36.2 5 2
+github.com/go-think/think/think.go:39.60,43.2 3 2
+github.com/go-think/think/think.go:46.62,48.2 1 0
+github.com/go-think/think/think.go:51.55,53.2 1 2
+github.com/go-think/think/think.go:60.40,70.32 6 2
+github.com/go-think/think/think.go:70.32,72.3 1 2
+github.com/go-think/think/think.go:74.2,76.12 2 2
+github.com/go-think/think/think.go:76.12,81.17 3 2
+github.com/go-think/think/think.go:81.17,85.4 3 0
+github.com/go-think/think/think.go:88.2,88.14 1 2
+github.com/go-think/think/think.go:97.30,101.2 3 2
diff --git a/go.mod b/go.mod
index e6e3961..8c31113 100644
--- a/go.mod
+++ b/go.mod
@@ -1,8 +1,15 @@
-module github.com/forgoer/thinkgo
+module github.com/go-think/think
-go 1.14
+go 1.23.0
require (
+ github.com/go-think/log v1.1.0
github.com/gomodule/redigo v1.8.8
github.com/stretchr/testify v1.7.0
)
+
+require (
+ github.com/davecgh/go-spew v1.1.0 // indirect
+ github.com/pmezard/go-difflib v1.0.0 // indirect
+ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
+)
diff --git a/go.sum b/go.sum
index bc94f23..da759e0 100644
--- a/go.sum
+++ b/go.sum
@@ -1,5 +1,7 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/go-think/log v1.1.0 h1:rJDBERVXIe5hhc0Gh4gLoZBCA2HUIrnYcatDbTgQskQ=
+github.com/go-think/log v1.1.0/go.mod h1:ZFn2AuRp9WxwF943XoT7nMvE5OEMf/efPWpBNZ0knxA=
github.com/gomodule/redigo v1.8.8 h1:f6cXq6RRfiyrOJEV7p3JhLDlmawGBVBBP1MggY8Mo4E=
github.com/gomodule/redigo v1.8.8/go.mod h1:7ArFNvsTjH8GMMzB4uy1snslv2BwmginuMs06a1uzZE=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
diff --git a/think/handler.go b/handler.go
similarity index 86%
rename from think/handler.go
rename to handler.go
index c5632aa..359b02e 100644
--- a/think/handler.go
+++ b/handler.go
@@ -1,7 +1,7 @@
-package think
+package thinkgo
import (
- "github.com/forgoer/thinkgo/context"
+ "github.com/go-think/think/context"
)
// HandlerFunc Handle the application.
diff --git a/log.go b/log.go
new file mode 100644
index 0000000..204dc00
--- /dev/null
+++ b/log.go
@@ -0,0 +1 @@
+package thinkgo
diff --git a/log/formatter/formatter.go b/log/formatter/formatter.go
deleted file mode 100644
index 90b0ab0..0000000
--- a/log/formatter/formatter.go
+++ /dev/null
@@ -1,8 +0,0 @@
-package formatter
-
-import "github.com/forgoer/thinkgo/log/record"
-
-type Formatter interface {
- Format(r record.Record) string
- FormatBatch(rs []record.Record) string
-}
diff --git a/log/formatter/json_formatter.go b/log/formatter/json_formatter.go
deleted file mode 100644
index b88d521..0000000
--- a/log/formatter/json_formatter.go
+++ /dev/null
@@ -1,35 +0,0 @@
-package formatter
-
-import (
- "encoding/json"
- "github.com/forgoer/thinkgo/log/record"
-)
-
-type JsonFormatter struct {
-}
-
-func NewJsonFormatter() *JsonFormatter {
- j := &JsonFormatter{}
- return j
-}
-
-func (f *JsonFormatter) Format(r record.Record) string {
- normalized := make(map[string]interface{})
-
- normalized["message"] = r.Message
- normalized["level"] = r.Level
- normalized["level_name"] = r.LevelName
- normalized["channel"] = r.Channel
- normalized["datetime"] = r.Datetime.Local().Format("2006-01-02 15:04:05.000")
-
- output, _ := json.Marshal(normalized)
- return string(output) + "\n"
-}
-
-func (f *JsonFormatter) FormatBatch(rs []record.Record) string {
- message := ""
- for _, r := range rs {
- message = message + f.Format(r)
- }
- return message
-}
diff --git a/log/formatter/line_formatter.go b/log/formatter/line_formatter.go
deleted file mode 100644
index 96ba0a8..0000000
--- a/log/formatter/line_formatter.go
+++ /dev/null
@@ -1,23 +0,0 @@
-package formatter
-
-import "github.com/forgoer/thinkgo/log/record"
-
-type LineFormatter struct {
-}
-
-func NewLineFormatter() *LineFormatter {
- f := &LineFormatter{}
- return f
-}
-
-func (f *LineFormatter) Format(r record.Record) string {
- return "[" + r.Datetime.Local().Format("2006-01-02 15:04:05.000") + "]" + r.Channel + "." + r.LevelName + ": " + r.Message + "\n"
-}
-
-func (f *LineFormatter) FormatBatch(rs []record.Record) string {
- message := ""
- for _, r := range rs {
- message = message + f.Format(r)
- }
- return message
-}
diff --git a/log/handler/console.go b/log/handler/console.go
deleted file mode 100644
index a64c93f..0000000
--- a/log/handler/console.go
+++ /dev/null
@@ -1,69 +0,0 @@
-package handler
-
-import (
- "os"
- "sync"
-
- "github.com/forgoer/thinkgo/log/record"
-)
-
-type brush func(string) string
-
-func newBrush(color string) brush {
- pre := "\033["
- reset := "\033[0m"
- return func(text string) string {
- return pre + color + "m" + text + reset
- }
-}
-
-var colors = map[record.Level]brush{
- record.EMERGENCY: newBrush("1;41"), // Emergency Red background
- record.ALERT: newBrush("1;35"), // Alert purple
- record.CRITICAL: newBrush("1;34"), // Critical blue
- record.ERROR: newBrush("1;31"), // Error red
- record.WARNING: newBrush("1;33"), // Warn yellow
- record.INFO: newBrush("1;36"), // Informational sky blue
- record.DEBUG: newBrush("1;32"), // Debug green
- record.NOTICE: newBrush("1;32"), // Trace green
-}
-
-type ConsoleHandler struct {
- Handler
- sync.Mutex
- level record.Level
-
- bubble bool
-}
-
-func NewConsoleHandler(level record.Level) *ConsoleHandler {
- return &ConsoleHandler{
- level: level,
- bubble: true,
- }
-}
-
-// IsHandling Checks whether the given record will be handled by this handler.
-func (h *ConsoleHandler) IsHandling(r record.Record) bool {
- return r.Level >= h.level
-}
-
-// Handle Handles a record.
-func (h *ConsoleHandler) Handle(r record.Record) bool {
- if !h.IsHandling(r) {
- return false
- }
-
- r.Formatted = h.GetFormatter().Format(r)
-
- h.write(r)
-
- return false == h.bubble
-}
-
-func (h *ConsoleHandler) write(r record.Record) {
- h.Lock()
- defer h.Unlock()
- message := colors[r.Level](r.Formatted)
- os.Stdout.Write(append([]byte(message)))
-}
diff --git a/log/handler/file.go b/log/handler/file.go
deleted file mode 100644
index c63dff2..0000000
--- a/log/handler/file.go
+++ /dev/null
@@ -1,94 +0,0 @@
-package handler
-
-import (
- "os"
- "path"
- "strings"
- "sync"
- "time"
-
- "github.com/forgoer/thinkgo/log/record"
-)
-
-type FileHandler struct {
- Handler
- sync.Mutex
- level record.Level
- bubble bool
- filename string
-
- filenameFormat string
- dateFormat string
- timedFilename string
-
- rotate bool
-}
-
-func NewFileHandler(filename string, level record.Level) *FileHandler {
- h := &FileHandler{
- level: level,
- bubble: true,
- filename: filename,
- filenameFormat: "{filename}-{date}",
- dateFormat: "2006-01-02",
- }
- // h.timedFilename = h.GetTimedFilename()
- return h
-}
-
-// IsHandling Checks whether the given record will be handled by this handler.
-func (h *FileHandler) IsHandling(r record.Record) bool {
- return r.Level >= h.level
-}
-
-// Handle Handles a record.
-func (h *FileHandler) Handle(r record.Record) bool {
- if !h.IsHandling(r) {
- return false
- }
-
- r.Formatted = h.GetFormatter().Format(r)
-
- h.write(r)
-
- return false == h.bubble
-}
-
-// SetLevel Sets minimum logging level at which this handler will be triggered.
-func (h *FileHandler) SetLevel(level record.Level) {
- h.level = level
-}
-
-func (h *FileHandler) write(r record.Record) {
- h.Lock()
- defer h.Unlock()
- file, _ := os.OpenFile(h.GetFilename(), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644)
- defer file.Close()
- file.Write([]byte(r.Formatted))
-}
-
-// GetFilename Gets the filename.
-func (h *FileHandler) GetFilename() string {
- if !h.rotate {
- return h.filename
- }
-
- return h.GetTimedFilename()
-}
-
-// GetTimedFilename Gets the timed filename.
-func (h *FileHandler) GetTimedFilename() string {
- dirname := path.Dir(h.filename)
- filename := path.Base(h.filename)
- fileExt := path.Ext(h.filename)
- filename = strings.TrimSuffix(filename, fileExt)
-
- timedFilename := strings.Replace(path.Join(dirname, h.filenameFormat), "{filename}", filename, -1)
- timedFilename = strings.Replace(timedFilename, "{date}", time.Now().Local().Format(h.dateFormat), -1)
-
- if len(fileExt) > 0 {
- timedFilename = timedFilename + fileExt
- }
-
- return timedFilename
-}
diff --git a/log/handler/file_test.go b/log/handler/file_test.go
deleted file mode 100644
index 0e72cbc..0000000
--- a/log/handler/file_test.go
+++ /dev/null
@@ -1,46 +0,0 @@
-package handler
-
-import (
- "io/ioutil"
- "os"
- "path"
- "strings"
- "testing"
- "time"
-
- "github.com/forgoer/thinkgo/log/record"
-)
-
-func TestNewFileHandler(t *testing.T) {
- filename := path.Join(os.TempDir(), "thinkgo.log")
-
- h := NewFileHandler(filename, record.DEBUG)
- filename = h.GetFilename()
-
- os.Remove(filename)
-
- message := "Log write to file"
- r := getRecord(message)
- h.Handle(r)
-
- b, err := ioutil.ReadFile(filename)
- if err != nil {
- t.Error(err)
- }
- content := string(b)
-
- if !strings.Contains(content, message) {
- t.Error("test FileHandler error")
- }
- t.Log(filename, content)
-}
-
-func getRecord(message string) record.Record {
- return record.Record{
- Level: 200,
- Message: message,
- LevelName: "INFO",
- Channel: "testing",
- Datetime: time.Now(),
- }
-}
diff --git a/log/handler/handler.go b/log/handler/handler.go
deleted file mode 100644
index 5a0d26f..0000000
--- a/log/handler/handler.go
+++ /dev/null
@@ -1,29 +0,0 @@
-package handler
-
-import (
- "github.com/forgoer/thinkgo/log/formatter"
- "github.com/forgoer/thinkgo/log/record"
-)
-
-type Handler struct {
- formatter formatter.Formatter
- level record.Level
-}
-
-// GetFormatter Gets the formatter.
-func (h *Handler) GetFormatter() formatter.Formatter {
- if h.formatter == nil {
- h.formatter = h.getDefaultFormatter()
- }
- return h.formatter
-}
-
-// SetFormatter Sets the formatter.
-func (h *Handler) SetFormatter(f formatter.Formatter) *Handler {
- h.formatter = f
- return h
-}
-
-func (h *Handler) getDefaultFormatter() formatter.Formatter {
- return formatter.NewLineFormatter()
-}
diff --git a/log/handler/rotate.go b/log/handler/rotate.go
deleted file mode 100644
index 3ffaa82..0000000
--- a/log/handler/rotate.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package handler
-
-import (
- "github.com/forgoer/thinkgo/log/record"
-)
-
-func NewRotateHandler(filename string, level record.Level) *FileHandler {
- // h.timedFilename = h.GetTimedFilename()
- fileHandler := NewFileHandler(filename, level)
- fileHandler.rotate = true
-
- return fileHandler
-}
diff --git a/log/handler/rotate_test.go b/log/handler/rotate_test.go
deleted file mode 100644
index 9669d03..0000000
--- a/log/handler/rotate_test.go
+++ /dev/null
@@ -1,34 +0,0 @@
-package handler
-
-import (
- "github.com/forgoer/thinkgo/log/record"
- "io/ioutil"
- "os"
- "path"
- "strings"
- "testing"
-)
-
-func TestRotateHandler(t *testing.T) {
- filename := path.Join(os.TempDir(), "thinkgo.log")
-
- h := NewRotateHandler(filename, record.DEBUG)
- filename = h.GetFilename()
-
- os.Remove(filename)
-
- message := "Log write to file"
- r := getRecord(message)
- h.Handle(r)
-
- b, err := ioutil.ReadFile(filename)
- if err != nil {
- t.Error(err)
- }
- content := string(b)
-
- if !strings.Contains(content, message) {
- t.Error("test FileHandler error")
- }
- t.Log(filename, content)
-}
diff --git a/log/log.go b/log/log.go
deleted file mode 100644
index ed835a2..0000000
--- a/log/log.go
+++ /dev/null
@@ -1,61 +0,0 @@
-package log
-
-import (
- "github.com/forgoer/thinkgo/log/record"
-)
-
-var logger *Logger
-
-func init() {
- logger = NewLogger("develop", record.DEBUG)
-}
-
-// Debug Adds a log record at the DEBUG level.
-func Debug(format string, v ...interface{}) (bool, error) {
- return logger.Debug(format, v...)
-}
-
-// Info Adds a log record at the INFO level.
-func Info(format string, v ...interface{}) (bool, error) {
- return logger.Info(format, v...)
-}
-
-// Notice Adds a log record at the NOTICE level.
-func Notice(format string, v ...interface{}) (bool, error) {
- return logger.Notice(format, v...)
-}
-
-// Warn Adds a log record at the WARNING level.
-func Warn(format string, v ...interface{}) (bool, error) {
- return logger.Warn(format, v...)
-}
-
-// Error Adds a log record at the ERROR level.
-func Error(format string, v ...interface{}) (bool, error) {
- return logger.Error(format, v...)
-}
-
-// Crit Adds a log record at the CRITICAL level.
-func Crit(format string, v ...interface{}) (bool, error) {
- return logger.Crit(format, v...)
-}
-
-// Alert Adds a log record at the ALERT level.
-func Alert(format string, v ...interface{}) (bool, error) {
- return logger.Alert(format, v...)
-}
-
-// Emerg Adds a log record at the EMERGENCY level.
-func Emerg(format string, v ...interface{}) (bool, error) {
- return logger.Emerg(format, v...)
-}
-
-// GetLogger Get the default Logger
-func GetLogger() *Logger {
- return logger
-}
-
-// SetLogger Set the default Logger
-func SetLogger(l *Logger) {
- logger = l
-}
diff --git a/log/log_test.go b/log/log_test.go
deleted file mode 100644
index d5ea254..0000000
--- a/log/log_test.go
+++ /dev/null
@@ -1,64 +0,0 @@
-package log
-
-import (
- "errors"
- "io/ioutil"
- "os"
- "path"
- "strings"
- "testing"
-
- "github.com/forgoer/thinkgo/log/handler"
- "github.com/forgoer/thinkgo/log/record"
-)
-
-func TestLog(t *testing.T) {
- Debug("log with Debug")
- Info("log with Info")
- Notice("log with Notice")
- Warn("log with Warn")
- Error("log with Error")
- Crit("log with Crit")
- Alert("log with Alert")
- Emerg("log with Emerg")
-}
-
-func TestLogWithFileHandler(t *testing.T) {
-
- filename := path.Join(os.TempDir(), "thinkgo.log")
-
- h := handler.NewFileHandler(filename, record.INFO)
-
- l := NewLogger("testing", record.INFO)
- l.PushHandler(h)
-
- filename = h.GetTimedFilename()
-
- os.Remove(filename)
-
- message := "Log write to file"
-
- l.Debug(message)
-
- _, err := ioutil.ReadFile(filename)
- if err == nil {
- t.Error(errors.New("test FileHandler error"))
- }
-
-
- h.SetLevel(record.DEBUG)
- l = NewLogger("testing", record.DEBUG)
- l.PushHandler(h)
- l.Debug(message)
-
- b, err := ioutil.ReadFile(filename)
- if err != nil {
- t.Error(errors.New("test FileHandler error"))
- }
- content := string(b)
-
- if !strings.Contains(content, message) {
- t.Error("test FileHandler error")
- }
-
-}
diff --git a/log/logger.go b/log/logger.go
deleted file mode 100644
index 058a544..0000000
--- a/log/logger.go
+++ /dev/null
@@ -1,170 +0,0 @@
-package log
-
-import (
- "container/list"
- "errors"
- "fmt"
- "time"
-
- "github.com/forgoer/thinkgo/log/handler"
- "github.com/forgoer/thinkgo/log/record"
-)
-
-type Handler interface {
- IsHandling(r record.Record) bool
- Handle(r record.Record) bool
-}
-
-type Logger struct {
- name string
- level record.Level
- handlers *list.List
-}
-
-// NewLogger New a Logger instance
-func NewLogger(name string, level record.Level) *Logger {
- logger := &Logger{
- name: name,
- handlers: list.New(),
- level: level,
- }
- return logger
-}
-
-// GetName Gets the name
-func (logger *Logger) GetName(name string) string {
- return logger.name
-}
-
-// SetName Sets the name
-func (logger *Logger) SetName(name string) *Logger {
- logger.name = name
- return logger
-}
-
-// PushHandler Pushes a handler on to the stack.
-func (logger *Logger) PushHandler(handler Handler) *Logger {
- logger.handlers.PushFront(handler)
- return logger
-}
-
-// PopHandler Pops a handler from the stack
-func (logger *Logger) PopHandler() {
- front := logger.handlers.Front()
- if front != nil {
- logger.handlers.Remove(front)
- }
-}
-
-// SetHandlers Set handlers, replacing all existing ones.
-func (logger *Logger) SetHandlers(handlers []Handler) *Logger {
- count := len(handlers)
- for i := count - 1; i >= 0; i = i - 1 {
- logger.PushHandler(handlers[i])
- }
- return logger
-}
-
-// GetHandlers Returns a Handler slice
-func (logger *Logger) GetHandlers() []Handler {
- var handler []Handler
- for e := logger.handlers.Front(); e != nil; e = e.Next() {
- handler = append(handler, e.Value.(Handler))
- }
- return handler
-}
-
-// AddRecord Adds a log record.
-func (logger *Logger) AddRecord(level record.Level, format string, v ...interface{}) (bool, error) {
- if logger.handlers.Len() == 0 {
- logger.PushHandler(handler.NewConsoleHandler(logger.level))
- }
-
- levelName, err := GetLevelName(level)
- if err != nil {
- return false, err
- }
-
- handlerKey := false
- for e := logger.handlers.Front(); e != nil; e = e.Next() {
- h := e.Value.(Handler)
- if h.IsHandling(record.Record{Level: level}) {
- handlerKey = true
- break
- }
- }
- if !handlerKey {
- return false, nil
- }
-
- if len(v) > 0 {
- format = fmt.Sprintf(format, v...)
- }
-
- r := record.Record{
- Level: level,
- Message: format,
- LevelName: levelName,
- Channel: logger.name,
- Datetime: time.Now(),
- }
-
- for e := logger.handlers.Front(); e != nil; e = e.Next() {
- h := e.Value.(Handler)
- if h.Handle(r) {
- break
- }
- }
-
- return true, nil
-}
-
-// Debug Adds a log record at the DEBUG level.
-func (logger *Logger) Debug(format string, v ...interface{}) (bool, error) {
- return logger.AddRecord(record.DEBUG, format, v...)
-}
-
-// Info Adds a log record at the INFO level.
-func (logger *Logger) Info(format string, v ...interface{}) (bool, error) {
- return logger.AddRecord(record.INFO, format, v...)
-}
-
-// Notice Adds a log record at the NOTICE level.
-func (logger *Logger) Notice(format string, v ...interface{}) (bool, error) {
- return logger.AddRecord(record.NOTICE, format, v...)
-}
-
-// Warn Adds a log record at the WARNING level.
-func (logger *Logger) Warn(format string, v ...interface{}) (bool, error) {
- return logger.AddRecord(record.WARNING, format, v...)
-}
-
-// Error Adds a log record at the ERROR level.
-func (logger *Logger) Error(format string, v ...interface{}) (bool, error) {
- return logger.AddRecord(record.ERROR, format, v...)
-}
-
-// Crit Adds a log record at the CRITICAL level.
-func (logger *Logger) Crit(format string, v ...interface{}) (bool, error) {
- return logger.AddRecord(record.CRITICAL, format, v...)
-}
-
-// Alert Adds a log record at the ALERT level.
-func (logger *Logger) Alert(format string, v ...interface{}) (bool, error) {
- return logger.AddRecord(record.ALERT, format, v...)
-}
-
-// Emerg Adds a log record at the EMERGENCY level.
-func (logger *Logger) Emerg(format string, v ...interface{}) (bool, error) {
- return logger.AddRecord(record.EMERGENCY, format, v...)
-}
-
-// Gets the name of the logging level.
-func GetLevelName(level record.Level) (string, error) {
- levels := record.GetLevels()
- l, ok := levels[level]
- if !ok {
- return l, errors.New(fmt.Sprintf("Level %d is not defined", level))
- }
- return l, nil
-}
diff --git a/log/record/record.go b/log/record/record.go
deleted file mode 100644
index e79cf2a..0000000
--- a/log/record/record.go
+++ /dev/null
@@ -1,63 +0,0 @@
-package record
-
-import (
- "strings"
- "time"
-)
-
-type Level int
-
-const (
- // DEBUG Detailed debug information
- DEBUG Level = 100
- // INFO Interesting events
- INFO Level = 200
- // NOTICE Uncommon events
- NOTICE Level = 250
- // WARNING Exceptional occurrences that are not errors
- WARNING Level = 300
- // ERROR Runtime errors
- ERROR Level = 400
- // CRITICAL Critical conditions
- CRITICAL Level = 500
- // ALERT Action must be taken immediately
- ALERT Level = 550
- // EMERGENCY Urgent alert.
- EMERGENCY Level = 600
-)
-
-// Logging levels from syslog protocol defined in RFC 5424
-var levels = map[Level]string{
- DEBUG: "DEBUG",
- INFO: "INFO",
- NOTICE: "NOTICE",
- WARNING: "WARNING",
- ERROR: "ERROR",
- CRITICAL: "CRITICAL",
- ALERT: "ALERT",
- EMERGENCY: "EMERGENCY",
-}
-
-type Record struct {
- Level Level
- Message string
- LevelName string
- Channel string
- Datetime time.Time
- Formatted string
-}
-
-// GetLevels returns levels map
-func GetLevels() map[Level]string {
- return levels
-}
-
-// GetLevel Parse the string level into a Level constant.
-func GetLevel(levelKey string) Level {
- for level, s := range levels {
- if strings.ToUpper(levelKey) == s {
- return level
- }
- }
- return DEBUG
-}
diff --git a/pipeline.go b/pipeline.go
index 2f8cc20..69621b0 100644
--- a/pipeline.go
+++ b/pipeline.go
@@ -5,13 +5,12 @@ import (
"html/template"
"net/http"
- "github.com/forgoer/thinkgo/context"
- "github.com/forgoer/thinkgo/router"
- "github.com/forgoer/thinkgo/think"
+ "github.com/go-think/think/context"
+ "github.com/go-think/think/router"
)
type Pipeline struct {
- handlers []think.Handler
+ handlers []Handler
pipeline *list.List
passable *context.Request
}
@@ -25,13 +24,13 @@ func NewPipeline() *Pipeline {
}
// Pipe Push a Middleware Handler to the pipeline
-func (p *Pipeline) Pipe(m think.Handler) *Pipeline {
+func (p *Pipeline) Pipe(m Handler) *Pipeline {
p.pipeline.PushBack(m)
return p
}
// Pipe Batch push Middleware Handlers to the pipeline
-func (p *Pipeline) Through(hls []think.Handler) *Pipeline {
+func (p *Pipeline) Through(hls []Handler) *Pipeline {
for _, hl := range hls {
p.Pipe(hl)
}
@@ -67,13 +66,13 @@ func (p *Pipeline) ServeHTTP(w http.ResponseWriter, r *http.Request) {
result.(router.Response).Send(w)
break
case template.HTML:
- think.Html(string(result.(template.HTML))).Send(w)
+ Html(string(result.(template.HTML))).Send(w)
break
case http.Handler:
result.(http.Handler).ServeHTTP(w, r)
break
default:
- think.Response(result).Send(w)
+ Response(result).Send(w)
break
}
}
@@ -82,12 +81,12 @@ func (p *Pipeline) handler(passable *context.Request, e *list.Element) interface
if e == nil {
return nil
}
- hl := e.Value.(think.Handler)
+ hl := e.Value.(Handler)
result := hl.Process(passable, p.closure(e))
return result
}
-func (p *Pipeline) closure(e *list.Element) think.Closure {
+func (p *Pipeline) closure(e *list.Element) Closure {
return func(req *context.Request) interface{} {
e = e.Next()
return p.handler(req, e)
diff --git a/think/recover_handler.go b/recover_handler.go
similarity index 95%
rename from think/recover_handler.go
rename to recover_handler.go
index b8a20d2..fe2d8da 100644
--- a/think/recover_handler.go
+++ b/recover_handler.go
@@ -1,11 +1,12 @@
-package think
+package thinkgo
import (
"fmt"
- "github.com/forgoer/thinkgo/context"
"net/http/httputil"
"runtime"
"strings"
+
+ "github.com/go-think/think/context"
)
type RecoverHandler struct {
diff --git a/think/response.go b/response.go
similarity index 96%
rename from think/response.go
rename to response.go
index 9aa0aa5..a2f10e3 100644
--- a/think/response.go
+++ b/response.go
@@ -1,4 +1,4 @@
-package think
+package thinkgo
import (
"encoding/json"
@@ -6,7 +6,7 @@ import (
"fmt"
"reflect"
- "github.com/forgoer/thinkgo/context"
+ "github.com/go-think/think/context"
)
// Json Create a new HTTP Response with JSON data
diff --git a/think/route_hendler.go b/route_hendler.go
similarity index 84%
rename from think/route_hendler.go
rename to route_hendler.go
index a887df5..dfcfaed 100644
--- a/think/route_hendler.go
+++ b/route_hendler.go
@@ -1,8 +1,8 @@
-package think
+package thinkgo
import (
- "github.com/forgoer/thinkgo/context"
- "github.com/forgoer/thinkgo/router"
+ "github.com/go-think/think/context"
+ "github.com/go-think/think/router"
)
type RouteHandler struct {
diff --git a/router/middleware.go b/router/middleware.go
index d1dda41..e5551a4 100644
--- a/router/middleware.go
+++ b/router/middleware.go
@@ -3,7 +3,7 @@ package router
import (
"net/http"
- "github.com/forgoer/thinkgo/context"
+ "github.com/go-think/think/context"
)
// Response an HTTP response interface
diff --git a/router/pipeline.go b/router/pipeline.go
index e8d2136..9f79908 100644
--- a/router/pipeline.go
+++ b/router/pipeline.go
@@ -3,7 +3,7 @@ package router
import (
"container/list"
- "github.com/forgoer/thinkgo/context"
+ "github.com/go-think/think/context"
)
type Pipeline struct {
diff --git a/router/router.go b/router/router.go
index d4516df..35b6f77 100644
--- a/router/router.go
+++ b/router/router.go
@@ -1,7 +1,7 @@
package router
import (
- "github.com/forgoer/thinkgo/context"
+ "github.com/go-think/think/context"
)
// RunRoute Return the response for the given rule.
diff --git a/router/rule.go b/router/rule.go
index 6d30502..3516bef 100644
--- a/router/rule.go
+++ b/router/rule.go
@@ -5,7 +5,7 @@ import (
"regexp"
"strings"
- "github.com/forgoer/thinkgo/context"
+ "github.com/go-think/think/context"
)
// Rule Route rule
diff --git a/router/static.go b/router/static.go
index 0cea2e0..67a3a69 100644
--- a/router/static.go
+++ b/router/static.go
@@ -3,7 +3,7 @@ package router
import (
"net/http"
- "github.com/forgoer/thinkgo/filesystem"
+ "github.com/go-think/think/filesystem"
)
type staticHandle struct {
diff --git a/session/file-handler.go b/session/file-handler.go
index ed16a4e..37ca505 100644
--- a/session/file-handler.go
+++ b/session/file-handler.go
@@ -4,7 +4,7 @@ import (
"path"
"time"
- "github.com/forgoer/thinkgo/filesystem"
+ "github.com/go-think/think/filesystem"
)
type FileHandler struct {
diff --git a/think/session_handler.go b/session_handler.go
similarity index 88%
rename from think/session_handler.go
rename to session_handler.go
index ce1d487..e5dd044 100644
--- a/think/session_handler.go
+++ b/session_handler.go
@@ -1,9 +1,9 @@
-package think
+package thinkgo
import (
- "github.com/forgoer/thinkgo/config"
- "github.com/forgoer/thinkgo/context"
- "github.com/forgoer/thinkgo/session"
+ "github.com/go-think/think/config"
+ "github.com/go-think/think/context"
+ "github.com/go-think/think/session"
)
type SessionHandler struct {
diff --git a/think.go b/think.go
index 1c13b66..6d2d4c7 100644
--- a/think.go
+++ b/think.go
@@ -2,16 +2,16 @@ package thinkgo
import (
"fmt"
- "github.com/forgoer/thinkgo/log"
- "github.com/forgoer/thinkgo/log/record"
"net/http"
+ "github.com/go-think/log"
+ "github.com/go-think/log/record"
+
"time"
- "github.com/forgoer/thinkgo/config"
- "github.com/forgoer/thinkgo/helper"
- "github.com/forgoer/thinkgo/router"
- "github.com/forgoer/thinkgo/think"
+ "github.com/go-think/think/config"
+ "github.com/go-think/think/helper"
+ "github.com/go-think/think/router"
)
type registerRouteFunc func(route *router.Route)
@@ -19,13 +19,13 @@ type registerRouteFunc func(route *router.Route)
type registerConfigFunc func()
type Think struct {
- App *think.Application
- handlers []think.HandlerFunc
+ App *Application
+ handlers []HandlerFunc
}
// New Create The Application
func New() *Think {
- application := think.NewApplication()
+ application := NewApplication()
application.Logger = log.NewLogger("develop", record.DEBUG)
t := &Think{
App: application,
@@ -48,7 +48,7 @@ func (th *Think) RegisterConfig(register registerConfigFunc) {
}
// RegisterConfig Register Config
-func (th *Think) RegisterHandler(handler think.HandlerFunc) {
+func (th *Think) RegisterHandler(handler HandlerFunc) {
th.handlers = append(th.handlers, handler)
}
@@ -64,14 +64,14 @@ func (th *Think) Run(params ...string) {
var addrs = helper.ParseAddr(params...)
// register route handler
- th.RegisterHandler(think.NewRouteHandler)
+ th.RegisterHandler(NewRouteHandler)
pipeline := NewPipeline()
for _, h := range th.handlers {
pipeline.Pipe(h(th.App))
}
- th.App.Logger.Debug("\r\nLoaded routes:\r\n%s",string(th.App.GetRoute().Dump()))
+ th.App.Logger.Debug("\r\nLoaded routes:\r\n%s", string(th.App.GetRoute().Dump()))
go func() {
th.App.Logger.Debug("ThinkGo server running on http://%s", addrs)
diff --git a/think_test.go b/think_test.go
index 93b2550..8c78007 100644
--- a/think_test.go
+++ b/think_test.go
@@ -3,7 +3,6 @@ package thinkgo
import (
"crypto/tls"
"fmt"
- "github.com/forgoer/thinkgo/context"
"io"
"io/ioutil"
"net/http"
@@ -12,11 +11,12 @@ import (
"testing"
"time"
+ "github.com/go-think/think/context"
+
"github.com/stretchr/testify/assert"
- "github.com/forgoer/thinkgo/think"
)
-func testRequest(t *testing.T, method, url string, data url.Values, res *think.Res) {
+func testRequest(t *testing.T, method, url string, data url.Values, res *Res) {
var err error
var resp *http.Response
@@ -66,16 +66,16 @@ func TestRunWithPort(t *testing.T) {
th := New()
go func() {
- th.RegisterRoute(func(route *think.Route) {
- route.Get("/", func(req *think.Req) *think.Res {
- return think.Text("it worked")
+ th.RegisterRoute(func(route *Route) {
+ route.Get("/", func(req *Req) *Res {
+ return Text("it worked")
})
})
// listen and serve on 0.0.0.0:9011
th.Run(":9012")
}()
- time.Sleep(5 * time.Millisecond)
+ time.Sleep(2 * time.Second)
testRequest(t, "get", "http://localhost:9012/", nil, context.NewResponse().SetContent("it worked"))
}
@@ -84,14 +84,14 @@ func TestThink_Run(t *testing.T) {
th := New()
go func() {
- th.RegisterRoute(func(route *think.Route) {
- route.Get("/", func(req *think.Req) interface{} {
+ th.RegisterRoute(func(route *Route) {
+ route.Get("/", func(req *Req) interface{} {
return "it worked"
})
- route.Get("/user/{name}", func(req *think.Req, name string) interface{} {
+ route.Get("/user/{name}", func(req *Req, name string) interface{} {
return fmt.Sprintf("Hello %s !", name)
})
- route.Post("/user", func(req *think.Req) interface{} {
+ route.Post("/user", func(req *Req) interface{} {
name, err := req.Post("name")
if err != nil {
panic(err)
@@ -106,7 +106,7 @@ func TestThink_Run(t *testing.T) {
th.Run()
}()
- time.Sleep(5 * time.Millisecond)
+ time.Sleep(2 * time.Second)
testRequest(t, "get", "http://localhost:9011/", nil, context.NewResponse().SetContent("it worked"))
testRequest(t, "get", "http://localhost:9011/user/thinkgo", nil, context.NewResponse().SetContent(fmt.Sprintf("Hello %s !", "thinkgo")))
diff --git a/think/type.go b/type.go
similarity index 50%
rename from think/type.go
rename to type.go
index 8701c42..d5a552a 100644
--- a/think/type.go
+++ b/type.go
@@ -1,8 +1,8 @@
-package think
+package thinkgo
import (
- "github.com/forgoer/thinkgo/context"
- "github.com/forgoer/thinkgo/router"
+ "github.com/go-think/think/context"
+ "github.com/go-think/think/router"
)
type (
From 20cc5e0f01ec91d3d8dee071646cd1ad4be72485 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 8 Dec 2025 12:44:31 +0000
Subject: [PATCH 2/2] Bump gopkg.in/yaml.v3 from
3.0.0-20200313102051-9f266ea9e77c to 3.0.1
Bumps gopkg.in/yaml.v3 from 3.0.0-20200313102051-9f266ea9e77c to 3.0.1.
---
updated-dependencies:
- dependency-name: gopkg.in/yaml.v3
dependency-version: 3.0.1
dependency-type: indirect
...
Signed-off-by: dependabot[bot]
---
go.mod | 2 +-
go.sum | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/go.mod b/go.mod
index 8c31113..c0bad68 100644
--- a/go.mod
+++ b/go.mod
@@ -11,5 +11,5 @@ require (
require (
github.com/davecgh/go-spew v1.1.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
- gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
+ gopkg.in/yaml.v3 v3.0.1 // indirect
)
diff --git a/go.sum b/go.sum
index da759e0..2700080 100644
--- a/go.sum
+++ b/go.sum
@@ -11,5 +11,6 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=