func TestScanCallback(ot *testing.T) { MustFlushDbV2() MustInsert("test_1", "abc") MustInsert("test_2", "abc") MustInsert("testno_3", "abc") scanSize = 2 outKey := []string{} err := ScanCallback("*", func(key string) error { outKey = append(outKey, key) return nil }) kmgTest.Equal(err, nil) kmgTest.Equal(len(outKey), 3) kmgTest.Ok(kmgStrings.IsInSlice(outKey, "test_1")) kmgTest.Ok(kmgStrings.IsInSlice(outKey, "test_2")) kmgTest.Ok(kmgStrings.IsInSlice(outKey, "testno_3")) scanSize = 10000 outKey = []string{} err = ScanCallback("test_*", func(key string) error { outKey = append(outKey, key) return nil }) kmgTest.Equal(err, nil) kmgTest.Equal(len(outKey), 2) kmgTest.Ok(kmgStrings.IsInSlice(outKey, "test_1")) kmgTest.Ok(kmgStrings.IsInSlice(outKey, "test_2")) sList, err := ScanWithOutputLimit("test_*", 1) kmgTest.Equal(err, nil) kmgTest.Equal(len(sList), 1) //benchmarkScanCallback() }
func MustForceModifyTable(tableConf Table) { MysqlFieldTypeList := mustMysqlGetTableFieldTypeList(tableConf.Name) dbFieldNameList := []string{} for _, row := range MysqlFieldTypeList { dbFieldNameList = append(dbFieldNameList, row.Name) } for _, f1 := range dbFieldNameList { found := false for f2 := range tableConf.FieldList { if f2 == f1 { found = true break } } if !found { MustExec(fmt.Sprintf("ALTER TABLE `%s` DROP COLUMN `%s`", tableConf.Name, f1)) } } for fieldName, fieldType := range tableConf.FieldList { if kmgStrings.IsInSlice(dbFieldNameList, fieldName) { for _, row := range MysqlFieldTypeList { if row.Name == fieldName { if !fieldType.GetMysqlFieldType().Equal(row.Type) { MustExec(fmt.Sprintf("ALTER TABLE `%s` CHANGE COLUMN `%s` `%s` %s NOT NULL", tableConf.Name, fieldName, fieldName, fieldType)) } break } } continue } MustAddNewField(tableConf, fieldName) } }
func MustCreateTable(tableConf Table) { sql := "CREATE TABLE IF NOT EXISTS `" + tableConf.Name + "` \n(" sqlItemList := []string{} hasPrimaryKey := false for fieldName, fieldType := range tableConf.FieldList { if tableConf.PrimaryKey == fieldName { hasPrimaryKey = true //continue } sqlField := "`" + fieldName + "` " + string(fieldType) if !kmgStrings.IsInSlice(tableConf.Null, fieldName) { sqlField += " NOT NULL" } sqlItemList = append(sqlItemList, sqlField) } if tableConf.PrimaryKey != "" { if !hasPrimaryKey { panic(fmt.Sprintf(`tableConf.PrimaryKey[%s], 但是这个主键不在字段列表里面`, tableConf.PrimaryKey)) } //sqlItemList = append(sqlItemList, "`"+tableConf.PrimaryKey+"` int(11) unsigned AUTO_INCREMENT") sqlItemList = append(sqlItemList, "PRIMARY KEY (`"+tableConf.PrimaryKey+"`)") } for _, group := range tableConf.UniqueKey { uniqueSql := "UNIQUE INDEX (" uniqueKeyList := []string{} for _, key := range group { uniqueKeyList = append(uniqueKeyList, "`"+key+"`") } uniqueSql += strings.Join(uniqueKeyList, ",") + ")" sqlItemList = append(sqlItemList, uniqueSql) } sql += strings.Join(sqlItemList, ",\n") sql += "\n) engine=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin" MustExec(sql) }
// 确保PATH里面包含 /usr/local/bin 和 /bin func RecoverPath() { pathenv := os.Getenv("PATH") pathList := strings.Split(pathenv, ":") change := false if !kmgStrings.IsInSlice(pathList, "/usr/local/bin") { change = true pathenv += ":/usr/local/bin" } if !kmgStrings.IsInSlice(pathList, "/bin") { change = true pathenv += ":/bin" } if change { os.Setenv("PATH", pathenv) } }
func MustAddNewField(tableConf Table, newFieldName string) { newFieldType := tableConf.FieldList[newFieldName] sql := "ALTER TABLE `" + tableConf.Name + "` ADD `" + newFieldName + "` " + string(newFieldType) if !kmgStrings.IsInSlice(tableConf.Null, newFieldName) { sql += " NOT NULL" } MustExec(sql) }
func (b *tBuilder) parsePkg(packageName string) *pkg { thisPkg := &pkg{ PackageName: packageName, } thisPkg.Dirpath = path.Join(kmgConfig.DefaultEnv().GetFirstGOPATH(), "src", packageName) if !kmgFile.MustDirectoryExist(thisPkg.Dirpath) { panic("[kmgViewResource] can not found dir " + thisPkg.Dirpath) } fileList := kmgFile.MustGetAllFileOneLevel(thisPkg.Dirpath) for _, file := range fileList { ext := kmgFile.GetExt(file) if ext == ".js" { thisPkg.JsFilePathList = append(thisPkg.JsFilePathList, file) importPathList := parseImportPath(file, kmgFile.MustReadFile(file)) thisPkg.ImportPathList = kmgStrings.SliceNoRepeatMerge(thisPkg.ImportPathList, importPathList) } else if ext == ".css" { thisPkg.CssFilePathList = append(thisPkg.CssFilePathList, file) importPathList := parseImportPath(file, kmgFile.MustReadFile(file)) thisPkg.ImportPathList = kmgStrings.SliceNoRepeatMerge(thisPkg.ImportPathList, importPathList) } else if kmgStrings.IsInSlice(allowResourceExt, ext) { name := filepath.Base(file) if b.ResourceFileNameMap[name] { panic("[kmgViewResource] resource file name " + name + " repeat path " + file) } thisPkg.ResourceFilePathList = append(thisPkg.ResourceFilePathList, file) } } sort.Strings(thisPkg.JsFilePathList) sort.Strings(thisPkg.CssFilePathList) for _, file := range thisPkg.JsFilePathList { // 这个泄漏信息比较严重.暂时关掉吧. //thisPkg.JsContent = append(thisPkg.JsContent, []byte("\n/* "+file+" */\n\n")...) thisPkg.JsContent = append(thisPkg.JsContent, kmgFile.MustReadFile(file)...) thisPkg.JsContent = append(thisPkg.JsContent, byte('\n')) } for _, file := range thisPkg.CssFilePathList { //thisPkg.CssContent = append(thisPkg.CssContent, []byte("\n/* "+file+"*/\n\n")...) thisPkg.CssContent = append(thisPkg.CssContent, kmgFile.MustReadFile(file)...) thisPkg.CssContent = append(thisPkg.CssContent, byte('\n')) } return thisPkg }
func MustModifyTable(tableConf Table) { MysqlFieldTypeList := mustMysqlGetTableFieldTypeList(tableConf.Name) dbFieldNameList := []string{} for _, row := range MysqlFieldTypeList { dbFieldNameList = append(dbFieldNameList, strings.ToLower(row.Name)) } for _, f1 := range dbFieldNameList { found := false for f2 := range tableConf.FieldList { if strings.EqualFold(f2, f1) { found = true break } } if !found { fmt.Printf("[kmgSql.SyncTable] 数据库中包含多余字段 Table[%s] Field[%s]\n", tableConf.Name, f1) } } for fieldName, fieldType := range tableConf.FieldList { if !kmgStrings.IsInSlice(dbFieldNameList, strings.ToLower(fieldName)) { MustAddNewField(tableConf, fieldName) continue } for _, row := range MysqlFieldTypeList { if row.Name == fieldName { if !fieldType.GetMysqlFieldType().Equal(row.Type) { fmt.Printf("[kmgSql.SyncTable] Table[%s] Field[%s] OldType[%s] NewType[%s] 数据库字段类型不一致\n", tableConf.Name, fieldName, row.Type.String(), fieldType.GetMysqlFieldType().String()) } break } if strings.EqualFold(row.Name, fieldName) { fmt.Printf("[kmgSql.SyncTable] Table[%s] OldField[%s] NewField[%s] 数据库字段大小写不一致\n", tableConf.Name, fieldName, row.Name) break } } } }
// 添加bytes的import项. // 这个是近似实现,golang的语法树确实有点复杂. func addImport(in []byte, pkgList []string) (out []byte) { status := addImportStatus(0) var hasFoundImport bool var lastImportParenthesesPos int outBuf := &bytes.Buffer{} for pos := 0; pos < len(in); pos++ { switch status { case addImportStatusNot: if bytes.HasPrefix(in[pos:], []byte("package")) { status = addImportStatusPackageToken } case addImportStatusPackageToken: if in[pos] == '\n' { status = addImportStatusPackageLine } case addImportStatusPackageLine: if bytes.HasPrefix(in[pos:], []byte("import")) { status = addImportStatusImportToken } else if bytes.HasPrefix(in[pos:], []byte("func ")) { status = addImportStatusImportImpossible } else if bytes.HasPrefix(in[pos:], []byte("type ")) { status = addImportStatusImportImpossible } else if bytes.HasPrefix(in[pos:], []byte("var ")) { status = addImportStatusImportImpossible } case addImportStatusImportToken: if in[pos] == '(' { status = addImportStatusImportParentheses1 lastImportParenthesesPos = pos } case addImportStatusImportParentheses1: if in[pos] == ')' { status = addImportStatusImportParentheses2 hasFoundImport = true var readedImportPathList []string importPkgPath := bytes.Split(in[lastImportParenthesesPos+1:pos], []byte{'\n'}) for _, p := range importPkgPath { p = bytes.TrimSpace(p) if len(p) == 0 { continue } readedImportPathList = append(readedImportPathList, string(p)) } for _, pkg := range pkgList { if !kmgStrings.IsInSlice(readedImportPathList, "\""+pkg+"\"") { outBuf.WriteString("\"" + pkg + "\"\n") } } } } outBuf.WriteByte(in[pos]) } if !hasFoundImport || status == addImportStatusImportImpossible { outBuf.Reset() isLastPackageToken := false hadAddImport := false for pos := 0; pos < len(in); pos++ { if !hadAddImport { if bytes.HasPrefix(in[pos:], []byte("package ")) { isLastPackageToken = true } else if in[pos] == '\n' { if isLastPackageToken { outBuf.WriteString("\nimport (") for _, pkg := range pkgList { outBuf.WriteString("\"" + pkg + "\"\n") } outBuf.WriteString(")") isLastPackageToken = false hadAddImport = true } } } outBuf.WriteByte(in[pos]) } } return outBuf.Bytes() }
func runFileHttpServer() { listenAddr := "" path := "" key := "" flag.StringVar(&listenAddr, "l", ":80", "listen address") flag.StringVar(&path, "path", "", "root path of the file server") flag.StringVar(&key, "key", "", "crypto key use to encrypt all request of this server") flag.Parse() var err error if path == "" { path, err = os.Getwd() if err != nil { fmt.Printf("os.Getwd() fail %s", err) return } } else { kmgErr.PanicIfError(os.Chdir(path)) } if key == "" { http.Handle("/", http.FileServer(http.Dir(path))) } if key != "" { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { realPath := filepath.Join(path, r.URL.Path) if !kmgFile.MustFileExist(realPath) { w.Write([]byte("File Not Exist")) return } if !kmgStrings.IsInSlice(cacheFilePathSlice, realPath) { cacheFilePathSlice = append(cacheFilePathSlice, realPath) } updateCache := func() { cacheFilePathEncryptMap[realPath] = kmgCrypto.CompressAndEncryptBytesEncodeV2( kmgCrypto.Get32PskFromString(key), kmgFile.MustReadFile(realPath), ) } checkCache := func() { lock.Lock() defer lock.Unlock() kmgCache.MustMd5FileChangeCache(realPath, []string{realPath}, func() { updateCache() }) } checkCache() //进程重启后,内存中的缓存掉了,但是文件系统的缓存还在 _, exist := cacheFilePathEncryptMap[realPath] if !exist { updateCache() } w.Write(cacheFilePathEncryptMap[realPath]) }) } fmt.Println("start server at", listenAddr) err = http.ListenAndServe(listenAddr, nil) if err != nil { fmt.Printf("http.ListenAndServe() fail %s", err) return } return }
func (repo *Repository) MustIsInParent(commitId string, parentCommitId string) bool { allParent := repo.MustGetAllParentCommitId(commitId) return kmgStrings.IsInSlice(allParent, parentCommitId) }