扫描代码是否有sql句柄没有关

2020-07-14  本文已影响0人  yellowone
package main

import (
    "flag"
    "fmt"
    "github.com/golang/glog"
    "io/ioutil"
    "os"
    "strings"
    "text/scanner"
)

type ScanInfo struct {
    Line    int
    IsClose bool
}

func main() {
    filePath := flag.String("filePath", "", "filePath")
    if strings.HasSuffix(*filePath, ".go") {
        ScanFile(*filePath)
        return
    }
    gopath := make([]string, 0)
    allGoPath, err := getAllFile(*filePath, gopath)
    if err != nil {
        glog.Error("打开文件夹失败", err)
        return
    }
    for _, fi := range allGoPath {
        ScanFile(fi)
    }
}

func getAllFile(pathname string, gopath []string) ([]string, error) {
    rd, err := ioutil.ReadDir(pathname)
    if err != nil {
        return nil, err
    }
    for _, fi := range rd {
        if fi.IsDir() {
            gopath, err = getAllFile(pathname+fi.Name()+"/", gopath)
            if err != nil {
                return nil, err
            }
        } else if strings.HasSuffix(fi.Name(), ".go") {
            gopath = append(gopath, pathname+fi.Name())
        }
    }
    return gopath, nil
}

func ScanFile(filePath string) []ScanInfo {
    fileInfo, err := os.Open(filePath)
    defer fileInfo.Close()
    if err != nil {
        glog.Error("文件打开错误", err)
        return nil
    }
    scanInfos := make([]ScanInfo, 0)
    scan := &scanner.Scanner{}
    scan.Init(fileInfo)
    shouldNext := true
    for i := scan.Scan(); i != scanner.EOF; {
        if scan.TokenText() == "func" {
            shouldNext = false
            i = scan.Scan()
            allLettle := make([]string, 0)
            shouldClosePre := make(map[string]*ScanInfo)
            shouldCloseRow := make(map[string]*ScanInfo)
            for scan.TokenText() != "func" {
                allLettle = append(allLettle, scan.TokenText())
                if scan.TokenText() == "Prepare" {
                    closeName := getParam(allLettle)
                    if len(closeName) > 0 {
                        if shouldClosePre[closeName] != nil {
                            fmt.Printf("%s:第%d行,有Prepare创建的句柄变量%s和前面的同名了\n", filePath, scan.Line, closeName)
                        }
                        shouldClosePre[closeName] = &ScanInfo{
                            Line: scan.Line,
                        }
                    }
                }
                for k := range shouldClosePre {
                    if k == scan.TokenText() {
                        scan.Scan()
                        allLettle = append(allLettle, scan.TokenText())
                        scan.Scan()
                        allLettle = append(allLettle, scan.TokenText())
                        if strings.Contains(scan.TokenText(), "Query") {
                            closeName := getParam(allLettle)
                            if len(closeName) > 0 {
                                if shouldClosePre[closeName] != nil {
                                    fmt.Printf("%s:第%d行,有row变量%s和前面的同名了\n", filePath, scan.Line, closeName)
                                }
                                shouldCloseRow[closeName] = &ScanInfo{
                                    Line: scan.Line,
                                }
                            }
                        }
                    }
                }
                if scan.TokenText() == "Close" && len(allLettle) >= 3 {
                    closeName := allLettle[len(allLettle)-3]
                    if shouldClosePre[closeName] != nil {
                        shouldClosePre[closeName].IsClose = true
                    }
                    if shouldCloseRow[closeName] != nil {
                        shouldCloseRow[closeName].IsClose = true
                    }
                }
                i = scan.Scan()
                if i == scanner.EOF {
                    break
                }
            }
            for k, v := range shouldClosePre {
                if !v.IsClose {
                    fmt.Printf("%s:第%d的句柄:%s没有关闭\n", filePath, v.Line, k)
                }
            }
            for k, v := range shouldCloseRow {
                if !v.IsClose {
                    fmt.Printf("%s:第%d的row:%s没有关闭\n", filePath, v.Line, k)
                }
            }
        }
        if shouldNext {
            i = scan.Scan()
        } else {
            shouldNext = true
        }
    }
    return scanInfos
}

func getParam(params []string) string {
    for i := len(params) - 1; i > 0; i-- {
        if params[i] == "," && i-1 >= 0 {
            return params[i-1]
        }
    }
    return ""
}

上一篇下一篇

猜你喜欢

热点阅读