├── .gitignore ├── LICENSE ├── README.md ├── backUp ├── bkHelper.go ├── export.go └── exportOne.go ├── bock.go ├── common ├── Objects.go ├── codec.go └── httpHelper.go ├── db ├── BaseDao.go ├── Idb.go └── MysqlDao.go ├── demo.go ├── ip.go ├── ipSpider └── IpSpider.go ├── main.go └── sqlBock ├── IBock.go └── Mysql ├── Bock.go └── Helper.go /.gitignore: -------------------------------------------------------------------------------- 1 | # Diy 2 | **/configs.* 3 | **/*.sql 4 | **/.DS_Store 5 | 6 | # Binaries for programs and plugins 7 | *.exe 8 | *.exe~ 9 | *.dll 10 | *.so 11 | *.dylib 12 | .idea/ 13 | **/*.xlsx 14 | 15 | # Test binary, build with `go test -c` 16 | *.test 17 | 18 | # Output of the go coverage tool, specifically when used with LiteIDE 19 | *.out 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 zhoutk 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # goTools 2 | > create some tools use go lang. 3 | 1. mysql exporter 4 | 2. ip spider 5 | 6 | ## 1. mysql exporter 7 | a tool can export mysql's table,data,views,function & stored procedure together or independent. 8 | 9 | ### characteristic 10 | - can export table, data, views, funcs. 11 | - multi grountinue to export many database together. 12 | - filter \xfffd. 13 | - solve the dependence of views. 14 | - can recieve a cli arg, which must be in table, data, view(s) & func, to export single content. 15 | 16 | ### configs.json 17 | you must create configs.json as: 18 | 19 | ``` 20 | { 21 | "db_name1": { 22 | "db_host": "192.168.1.8", 23 | "db_port": 3306, 24 | "db_user": "root", 25 | "db_pass": "123456", 26 | "db_name": "name1", 27 | "db_charset": "utf8mb4", 28 | "file_alias": "file name1" 29 | }, 30 | "db_name2": { 31 | "db_host": "localhost", 32 | "db_port": 3306, 33 | "db_user": "root", 34 | "db_pass": "123456", 35 | "db_name": "name2", 36 | "db_charset": "utf8mb4" 37 | }, 38 | "database_dialect": "mysql", 39 | "workDir": "/home/zhoutk/gocodes/goTools/" 40 | } 41 | ``` 42 | ### Instructions 43 | ``` 44 | git clone https://github.com/zhoutk/goTools 45 | cd goTools 46 | go get 47 | go run main.go 48 | 49 | go buid main.go 50 | ./main #export all things of database 51 | ./main table #export tables 52 | ./main data #export tables & data 53 | ./main views #export views 54 | ./main funcs #export funcs & stored procedures 55 | ``` 56 | 57 | ## 2. ip spider 58 | a tool can spider ip address info from appointed web page. 59 | 60 | ### characteristic 61 | - multi grountinue to spider web data. 62 | - write mysql batch. 63 | - update mysql batch. 64 | 65 | ### sql scripts 66 | you can create table use it: 67 | 68 | ``` 69 | CREATE TABLE `ip_addr_info` ( 70 | `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '索引,自动增长', 71 | `ip_addr_begin` varchar(32) NOT NULL DEFAULT '' COMMENT 'ip地址段开始', 72 | `ip_addr_end` varchar(32) DEFAULT '' COMMENT 'ip地址段结束', 73 | `province` varchar(32) DEFAULT '' COMMENT '所属省', 74 | `ip_comp` varchar(32) DEFAULT '' COMMENT '运营商', 75 | PRIMARY KEY (`id`), 76 | UNIQUE KEY `ip_addr` (`ip_addr_begin`,`ip_addr_end`) 77 | ) ENGINE=InnoDB AUTO_INCREMENT=7268 DEFAULT CHARSET=utf8 COMMENT='表'; 78 | ``` 79 | ### Instructions 80 | ``` 81 | git clone https://github.com/zhoutk/goTools 82 | cd goTools 83 | go get 84 | go run ip.go 85 | 86 | go buid ip.go 87 | ./ip 88 | ``` 89 | 90 | ## 3. rest server 91 | A framework for building micro service rapidly, safely & efficiently. 92 | 93 | ### characteristic 94 | - auto orm that can build sql from json object. 95 | - standard sql interface. 96 | - auto restful api serivce according to sql struct. 97 | 98 | ### Instructions 99 | ``` 100 | git clone https://github.com/zhoutk/goTools 101 | cd goTools 102 | go get 103 | go run bock.go 104 | 105 | go buid bock.go 106 | ./bock 107 | ``` 108 | -------------------------------------------------------------------------------- /backUp/bkHelper.go: -------------------------------------------------------------------------------- 1 | package backUp 2 | 3 | import ( 4 | "os" 5 | "fmt" 6 | "strings" 7 | "strconv" 8 | "time" 9 | "../common" 10 | "../db" 11 | ) 12 | 13 | func exportTables(fileName string, fields common.DbConnFields, flag common.OpFlag) error { 14 | sqlStr := "select CONSTRAINT_NAME,TABLE_NAME,COLUMN_NAME,REFERENCED_TABLE_SCHEMA," + 15 | "REFERENCED_TABLE_NAME,REFERENCED_COLUMN_NAME from information_schema.`KEY_COLUMN_USAGE` " + 16 | "where REFERENCED_TABLE_SCHEMA = ? " 17 | var values []interface{} 18 | values = append(values, fields.DbName) 19 | rs, err := db.ExecuteWithDbConn(sqlStr, values, fields) 20 | if err != nil { 21 | return err 22 | } 23 | rows := rs["rows"].([]map[string]interface{}) 24 | FKEYS := make(map[string]interface{}) 25 | for i := 0; i < len(rows); i++ { 26 | if _, ok := FKEYS[rows[i]["TABLE_NAME"].(string)+"."+rows[i]["CONSTRAINT_NAME"].(string)]; !ok { 27 | FKEYS[rows[i]["TABLE_NAME"].(string)+"."+rows[i]["CONSTRAINT_NAME"].(string)] = map[string]interface{}{ 28 | "constraintName": rows[i]["CONSTRAINT_NAME"], 29 | "sourceCols": make([]string, 0), 30 | "schema": rows[i]["REFERENCED_TABLE_SCHEMA"], 31 | "tableName": rows[i]["REFERENCED_TABLE_NAME"], 32 | "targetCols": make([]string, 0), 33 | } 34 | } 35 | FKEYS[rows[i]["TABLE_NAME"].(string)+"."+rows[i]["CONSTRAINT_NAME"].(string)].(map[string]interface{})["sourceCols"] = 36 | append(FKEYS[rows[i]["TABLE_NAME"].(string)+"."+rows[i]["CONSTRAINT_NAME"].(string)].(map[string]interface{})["sourceCols"].([]string), rows[i]["COLUMN_NAME"].(string)) 37 | FKEYS[rows[i]["TABLE_NAME"].(string)+"."+rows[i]["CONSTRAINT_NAME"].(string)].(map[string]interface{})["targetCols"] = 38 | append(FKEYS[rows[i]["TABLE_NAME"].(string)+"."+rows[i]["CONSTRAINT_NAME"].(string)].(map[string]interface{})["targetCols"].([]string), rows[i]["REFERENCED_COLUMN_NAME"].(string)) 39 | } 40 | 41 | sqlStr = "select TABLE_NAME,ENGINE,ROW_FORMAT,AUTO_INCREMENT,TABLE_COLLATION,CREATE_OPTIONS,TABLE_COMMENT" + 42 | " from information_schema.`TABLES` where TABLE_SCHEMA = ? and TABLE_TYPE = ? order by TABLE_NAME" 43 | values = make([]interface{}, 0) 44 | values = append(values, fields.DbName, "BASE TABLE") 45 | rs, err = db.ExecuteWithDbConn(sqlStr, values, fields) 46 | if err != nil { 47 | return err 48 | } 49 | tbRs := rs["rows"].([]map[string]interface{}) 50 | for _, tbAl := range tbRs { 51 | sqlStr = "SELECT `COLUMNS`.COLUMN_NAME,`COLUMNS`.COLUMN_TYPE,`COLUMNS`.IS_NULLABLE," + 52 | "`COLUMNS`.CHARACTER_SET_NAME,`COLUMNS`.COLUMN_DEFAULT,`COLUMNS`.EXTRA," + 53 | "`COLUMNS`.COLUMN_KEY,`COLUMNS`.COLUMN_COMMENT,`STATISTICS`.TABLE_NAME," + 54 | "`STATISTICS`.INDEX_NAME,`STATISTICS`.SEQ_IN_INDEX,`STATISTICS`.NON_UNIQUE," + 55 | "`COLUMNS`.COLLATION_NAME " + 56 | "FROM information_schema.`COLUMNS` " + 57 | "LEFT JOIN information_schema.`STATISTICS` ON " + 58 | "information_schema.`COLUMNS`.TABLE_NAME = `STATISTICS`.TABLE_NAME " + 59 | "AND information_schema.`COLUMNS`.COLUMN_NAME = information_schema.`STATISTICS`.COLUMN_NAME " + 60 | "AND information_schema.`STATISTICS`.table_schema = ? " + 61 | "where information_schema.`COLUMNS`.TABLE_NAME = ? and `COLUMNS`.table_schema = ?" 62 | values = make([]interface{}, 0) 63 | values = append(values, fields.DbName, tbAl["TABLE_NAME"], fields.DbName) 64 | rs, err = db.ExecuteWithDbConn(sqlStr, values, fields) 65 | if err != nil { 66 | return err 67 | } 68 | colRs := rs["rows"].([]map[string]interface{}) 69 | tableName := tbAl["TABLE_NAME"].(string) 70 | tableEngine := tbAl["ENGINE"].(string) 71 | //tableRowFormat := tbAl["ROW_FORMAT"] 72 | var tableAutoIncrement string 73 | if tbAl["AUTO_INCREMENT"] != nil { 74 | tableAutoIncrement = tbAl["AUTO_INCREMENT"].(string) 75 | } 76 | var tableCollation string 77 | if tbAl["TABLE_COLLATION"] != nil { 78 | tableCollation = tbAl["TABLE_COLLATION"].(string) 79 | } 80 | tableCharset := strings.Split(tableCollation, "_")[0] 81 | var tableCreateOptions string 82 | if tbAl["CREATE_OPTIONS"] != nil { 83 | tableCreateOptions = tbAl["CREATE_OPTIONS"].(string) 84 | } 85 | var tableComment string 86 | if tbAl["TABLE_COMMENT"] != nil { 87 | tableComment = tbAl["TABLE_COMMENT"].(string) 88 | } 89 | 90 | strExport := "DROP TABLE IF EXISTS `" + tbAl["TABLE_NAME"].(string) + "`;\n" 91 | strExport += "CREATE TABLE `" + tableName + "` (\n" 92 | 93 | priKey := make(map[string]interface{}) 94 | colKey := make(map[string]interface{}) 95 | mulKey := make(map[string]interface{}) 96 | theTableColSet := make(map[string]int) 97 | var allFields []string 98 | var defaultValue string 99 | for _, colAl := range colRs { 100 | if _, ok := theTableColSet[colAl["COLUMN_NAME"].(string)]; !ok { 101 | theTableColSet[colAl["COLUMN_NAME"].(string)] = 1 102 | allFields = append(allFields, "`"+colAl["COLUMN_NAME"].(string)+"`") 103 | if colAl["COLUMN_DEFAULT"] != nil && len(colAl["COLUMN_DEFAULT"].(string)) > 0 { 104 | if colAl["COLUMN_DEFAULT"] == "CURRENT_TIMESTAMP" { 105 | defaultValue = colAl["COLUMN_DEFAULT"].(string) 106 | } else { 107 | defaultValue = "'" + colAl["COLUMN_DEFAULT"].(string) + "'" 108 | } 109 | } 110 | var charSet string 111 | if colAl["CHARACTER_SET_NAME"] != nil && colAl["CHARACTER_SET_NAME"] != tableCharset { 112 | charSet = " CHARACTER SET " + colAl["CHARACTER_SET_NAME"].(string) 113 | } 114 | var collation string 115 | if colAl["COLLATION_NAME"] != nil && colAl["COLLATION_NAME"] != tableCollation { 116 | collation = " COLLATE " + colAl["COLLATION_NAME"].(string) 117 | } 118 | var nullStr string 119 | if colAl["IS_NULLABLE"] != nil && colAl["IS_NULLABLE"] == "NO" { 120 | nullStr = " NOT NULL" 121 | } 122 | if colAl["COLUMN_DEFAULT"] != nil && len(colAl["COLUMN_DEFAULT"].(string)) > 0 { 123 | defaultValue = " DEFAULT " + defaultValue 124 | } else { 125 | if colAl["IS_NULLABLE"] != nil && colAl["IS_NULLABLE"] == "NO" { 126 | defaultValue = "" 127 | } else { 128 | defaultValue = " DEFAULT NULL" 129 | } 130 | } 131 | var space string 132 | if colAl["EXTRA"] != nil && len(colAl["EXTRA"].(string)) > 0 { 133 | space = " " + colAl["EXTRA"].(string) 134 | } else { 135 | space = "" 136 | } 137 | var cstr string 138 | if colAl["COLUMN_COMMENT"] != nil && len(colAl["COLUMN_COMMENT"].(string)) > 0 { 139 | cstr = " COMMENT '" + escape(colAl["COLUMN_COMMENT"].(string)) + "'" 140 | } 141 | strExport += " `" + colAl["COLUMN_NAME"].(string) + "` " + colAl["COLUMN_TYPE"].(string) + charSet + collation + 142 | nullStr + defaultValue + space + cstr + ",\n" 143 | } 144 | if colAl["INDEX_NAME"] != nil && colAl["INDEX_NAME"].(string) == "PRIMARY" { 145 | if _, ok := priKey[colAl["INDEX_NAME"].(string)]; !ok { 146 | priKey[colAl["INDEX_NAME"].(string)] = make([]string, 0) 147 | } 148 | priKey[colAl["INDEX_NAME"].(string)] = append(priKey[colAl["INDEX_NAME"].(string)].([]string), colAl["COLUMN_NAME"].(string)) 149 | } else if colAl["INDEX_NAME"] != nil && colAl["NON_UNIQUE"] == "0" { 150 | if _, ok := colKey[colAl["INDEX_NAME"].(string)]; !ok { 151 | colKey[colAl["INDEX_NAME"].(string)] = make([]string, 0) 152 | } 153 | colKey[colAl["INDEX_NAME"].(string)] = append(colKey[colAl["INDEX_NAME"].(string)].([]string), colAl["COLUMN_NAME"].(string)) 154 | } else if colAl["INDEX_NAME"] != nil && colAl["NON_UNIQUE"] == "1" { 155 | if _, ok := mulKey[colAl["INDEX_NAME"].(string)]; !ok { 156 | mulKey[colAl["INDEX_NAME"].(string)] = make([]string, 0) 157 | } 158 | mulKey[colAl["INDEX_NAME"].(string)] = append(mulKey[colAl["INDEX_NAME"].(string)].([]string), colAl["COLUMN_NAME"].(string)) 159 | } 160 | } 161 | for _, v := range priKey { 162 | strExport += " PRIMARY KEY (`" + strings.Join(v.([]string), "`,`") + "`),\n" 163 | } 164 | for k, v := range colKey { 165 | strExport += " UNIQUE KEY `" + k + "` (`" + strings.Join(v.([]string), "`,`") + "`),\n" 166 | } 167 | for k, v := range mulKey { 168 | strExport += " KEY `" + k + "` (`" + strings.Join(v.([]string), "`,`") + "`),\n" 169 | } 170 | 171 | for k, v := range FKEYS { 172 | if strings.HasPrefix(k, tableName+".") { 173 | strExport += " CONSTRAINT `" + v.(map[string]interface{})["constraintName"].(string) + "` FOREIGN KEY (`" + 174 | strings.Join(v.(map[string]interface{})["sourceCols"].([]string), "`,`") + "`) REFERENCES `" + 175 | v.(map[string]interface{})["tableName"].(string) + "` (`" + 176 | strings.Join(v.(map[string]interface{})["targetCols"].([]string), "`,`") + "`),\n" 177 | } 178 | } 179 | if strings.HasSuffix(strExport, ",\n") { 180 | strExport = strExport[:len(strExport)-2] 181 | } 182 | 183 | var incr string 184 | if len(tableAutoIncrement) > 0 { 185 | incr = " AUTO_INCREMENT=" + tableAutoIncrement 186 | } 187 | var colla string 188 | if len(tableCollation) > 0 { 189 | colla = " COLLATE=" + tableCollation 190 | } 191 | strExport += "\n) ENGINE=" + tableEngine + incr + " DEFAULT CHARSET=" + 192 | tableCharset + colla + " " + tableCreateOptions + " COMMENT='" + tableComment + "';\n\n" 193 | 194 | writeToFile(fileName, strExport, true) //表结构导出 195 | 196 | if flag.Datum { 197 | err = exportTableData(fileName, fields, tableName, allFields) 198 | if err != nil { 199 | return err 200 | } 201 | } 202 | } 203 | return nil 204 | } 205 | 206 | func exportTableData(fileName string, fields common.DbConnFields, tableName string, allFields []string) error { 207 | sqlStr := "select " + strings.Join(allFields, ",") + " from " + tableName 208 | rs, err := db.ExecuteWithDbConn(sqlStr, make([]interface{}, 0), fields) 209 | if err != nil { 210 | return err 211 | } 212 | recordsRs := rs["rows"].([]map[string]interface{}) 213 | for _, ele := range recordsRs { 214 | strExport := "INSERT INTO `" + tableName + "` (" //+strings.Join(allFields, ",")+") VALUES (" 215 | var ks []string 216 | var vs []string 217 | for k, v := range ele { 218 | ks = append(ks, "`"+k+"`") 219 | elStr := "''" 220 | if v == nil { 221 | elStr = "null" 222 | } else if len(v.(string)) > 0 { 223 | elStr = "'" + escape(v.(string)) + "'" 224 | } 225 | vs = append(vs, elStr) 226 | } 227 | strExport += strings.Join(ks, ",") + ") VALUES (" + strings.Join(vs, ",") + ");\n" 228 | writeToFile(fileName, strExport, true) 229 | } 230 | writeToFile(fileName, "\n", true) 231 | return nil 232 | } 233 | 234 | func exportFuncs(fileName string, fields common.DbConnFields) error { 235 | sqlStr := "select name,type,param_list,returns,body from mysql.proc where db = ? " 236 | values := make([]interface{}, 0) 237 | values = append(values, fields.DbName) 238 | 239 | rs, err := db.ExecuteWithDbConn(sqlStr, values, fields) 240 | if err != nil { 241 | return err 242 | } 243 | fRs := rs["rows"].([]map[string]interface{}) 244 | 245 | for _, cstAl := range fRs { 246 | var rets string 247 | if cstAl["returns"] != nil && len(cstAl["returns"].(string)) > 0 { 248 | rets = " RETURNS " + cstAl["returns"].(string) 249 | } 250 | sqlStr = "DROP PROCEDURE IF EXISTS `" + cstAl["name"].(string) + "`;\nDELIMITER ;;\n" + 251 | "CREATE DEFINER=`root`@`%` " + cstAl["type"].(string) + " `" + cstAl["name"].(string) + 252 | "`(" + cstAl["param_list"].(string) + ")" + rets + "\n" + cstAl["body"].(string) + "\n" + 253 | ";;\nDELIMITER ;\n\n" 254 | writeToFile(fileName, sqlStr, true) 255 | } 256 | return nil 257 | } 258 | 259 | func exportViews(fileName string, fields common.DbConnFields) error { 260 | sqlStr := "select TABLE_NAME, VIEW_DEFINITION from information_schema.VIEWS where TABLE_SCHEMA = ? " 261 | values := make([]interface{}, 0) 262 | values = append(values, fields.DbName) 263 | rs, err := db.ExecuteWithDbConn(sqlStr, values, fields) 264 | if err != nil { 265 | return err 266 | } 267 | vRs := rs["rows"].([]map[string]interface{}) 268 | ps := make(map[string]string) 269 | vName := make([]string, 0) 270 | for _, v := range vRs { 271 | ps["`"+v["TABLE_NAME"].(string)+"`"] = v["VIEW_DEFINITION"].(string) 272 | vName = append(vName, "`"+v["TABLE_NAME"].(string)+"`") 273 | } 274 | rely1 := processRely(ps, &vName) 275 | rely := processRely(ps, &rely1) 276 | for _, al := range rely { 277 | viewStr := strings.Replace(ps[al], "`"+fields.DbName+"`.", "", -1) 278 | sqlStr = "DROP VIEW IF EXISTS " + al + ";\n" + "CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`%` " + 279 | " SQL SECURITY DEFINER VIEW " + al + " AS " + viewStr + ";\n\n" 280 | writeToFile(fileName, sqlStr, true) 281 | } 282 | return nil 283 | } 284 | 285 | func setSqlHeader(fields common.DbConnFields, fileName string) { 286 | content := "/* Mysql export \n" + 287 | "\n Host: " + fields.DbHost + 288 | "\n Port: " + strconv.Itoa(fields.DbPort) + 289 | "\n DataBase: " + fields.DbName + 290 | "\n Date: " + time.Now().Format("2006-01-02 15:04:05") + 291 | "\n\n Author: zhoutk@189.cn" + 292 | "\n Copyright: tlwl-2018" + 293 | "\n*/\n\n" 294 | writeToFile(fileName, content, false) 295 | writeToFile(fileName, "SET FOREIGN_KEY_CHECKS=0;\n\n", true) 296 | } 297 | 298 | func processRely(params map[string]string, relyOld *[]string) []string { 299 | rely := make([]string, 0) 300 | for _, k := range *relyOld { 301 | for bl := range params { 302 | if strings.Index(params[k], bl) > -1 { 303 | if findInArray(&rely, bl) < 0 { 304 | if findInArray(&rely, k) < 0 { 305 | rely = append(rely, bl) 306 | }else{ 307 | i := findInArray(&rely, k) 308 | lastStr := make([]string, len(rely) - i) 309 | copy(lastStr, rely[i:]) 310 | rely = append(rely[:i], bl) 311 | rely = append(rely, lastStr...) 312 | } 313 | }else{ 314 | if findInArray(&rely, k) > -1 { 315 | i := findInArray(&rely, k) 316 | j := findInArray(&rely, bl) 317 | if i < j { 318 | rely = append(rely[:j], rely[j+1:]...) 319 | lastStr := make([]string, len(rely) - i) 320 | copy(lastStr, rely[i:]) 321 | rely = append(rely[:i], bl) 322 | rely = append(rely, lastStr...) 323 | } 324 | } 325 | } 326 | } 327 | } 328 | if findInArray(&rely, k) < 0 { 329 | rely = append(rely, k) 330 | } 331 | } 332 | return rely 333 | } 334 | 335 | func findInArray(arry*[]string, value string) int{ 336 | if arry == nil { 337 | return -1 338 | }else{ 339 | for index, v := range *arry { 340 | if v == value { 341 | return index 342 | } 343 | } 344 | return -1 345 | } 346 | } 347 | 348 | func writeToFile(name string, content string, append bool) { 349 | var fileObj *os.File 350 | var err error 351 | if append{ 352 | fileObj, err = os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644) 353 | }else{ 354 | fileObj, err = os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) 355 | } 356 | if err != nil { 357 | fmt.Println("Failed to open the file", err.Error()) 358 | os.Exit(2) 359 | } 360 | defer fileObj.Close() 361 | if _, err := fileObj.WriteString(content); err != nil { 362 | fmt.Println(err) 363 | } 364 | } 365 | 366 | func escape(source string) string { 367 | var j int 368 | if len(source) == 0 { 369 | return "" 370 | } 371 | tempStr := source[:] 372 | desc := make([]byte, len(tempStr)*2) 373 | for i := 0; i < len(tempStr); i++ { 374 | flag := false 375 | var escape byte 376 | switch tempStr[i] { 377 | case '\r': 378 | flag = true 379 | escape = '\r' 380 | case '\n': 381 | flag = true 382 | escape = '\n' 383 | case '\\': 384 | flag = true 385 | escape = '\\' 386 | case '\'': 387 | flag = true 388 | escape = '\'' 389 | case '"': 390 | flag = true 391 | escape = '"' 392 | case '\032': 393 | flag = true 394 | escape = 'Z' 395 | default: 396 | } 397 | if flag { 398 | desc[j] = '\\' 399 | desc[j+1] = escape 400 | j = j + 2 401 | } else { 402 | desc[j] = tempStr[i] 403 | j = j + 1 404 | } 405 | } 406 | return string(desc[0:j]) 407 | } 408 | -------------------------------------------------------------------------------- /backUp/export.go: -------------------------------------------------------------------------------- 1 | package backUp 2 | 3 | import ( 4 | "strings" 5 | "encoding/json" 6 | "os" 7 | "../common" 8 | "fmt" 9 | ) 10 | 11 | func Export(flag common.OpFlag) (error) { 12 | var configs interface{} 13 | fr, err := os.Open("./configs.json") 14 | if err != nil { 15 | return err 16 | } 17 | decoder := json.NewDecoder(fr) 18 | err = decoder.Decode(&configs) 19 | if err != nil { 20 | return err 21 | } 22 | confs := configs.(map[string]interface{}) 23 | workDir := confs["workDir"].(string) 24 | ch := make(chan string) 25 | for key, value := range confs { 26 | if strings.HasPrefix(key, "db_") { 27 | dbConf := value.(map[string]interface{}) 28 | dbConn := common.DbConnFields{ 29 | DbHost: dbConf["db_host"].(string), 30 | DbPort: int(dbConf["db_port"].(float64)), 31 | DbUser: dbConf["db_user"].(string), 32 | DbPass: dbConf["db_pass"].(string), 33 | DbName: dbConf["db_name"].(string), 34 | DbCharset: dbConf["db_charset"].(string), 35 | } 36 | if dbConf["file_alias"] != nil { 37 | dbConn.FileAlias = dbConf["file_alias"].(string) 38 | } 39 | go ExportOne(dbConn, workDir, ch, flag) 40 | } 41 | } 42 | for key := range confs { 43 | if strings.HasPrefix(key, "db_") { 44 | fmt.Print( <- ch ) 45 | } 46 | } 47 | return nil 48 | } 49 | -------------------------------------------------------------------------------- /backUp/exportOne.go: -------------------------------------------------------------------------------- 1 | package backUp 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | "../common" 7 | "../db" 8 | ) 9 | 10 | func ExportOne(fields common.DbConnFields, workDir string, ch chan <- string, flag common.OpFlag) { 11 | var fileName string 12 | if fields.FileAlias == "" { 13 | fileName = workDir + fields.DbName + "-" + time.Now().Format("2006-01-02") + ".sql" 14 | }else{ 15 | fileName = workDir + fields.FileAlias + "-" + time.Now().Format("2006-01-02") + ".sql" 16 | } 17 | fmt.Println("Export ", fields.DbName , "\t start at \t", time.Now().Format("2006-01-02 15:04:05")) 18 | 19 | if err := db.TestDbConn(fields); err != nil { 20 | ch <- fmt.Sprintln("Error: ", fields.DbName, "\t test db connect throw, \t", err) 21 | return 22 | } 23 | 24 | setSqlHeader(fields, fileName) 25 | 26 | if flag.Tables { 27 | err := exportTables(fileName, fields, flag) 28 | if err != nil { 29 | ch <- fmt.Sprintln("Error: ", fields.DbName, "\t export tables throw, \t", err) 30 | return 31 | } 32 | } 33 | 34 | if flag.Views { 35 | err := exportViews(fileName, fields) 36 | if err != nil { 37 | ch <- fmt.Sprintln("Error: ", fields.DbName, "\t export views throw, \t", err) 38 | return 39 | } 40 | } 41 | 42 | if flag.Funcs { 43 | err := exportFuncs(fileName, fields) 44 | if err != nil { 45 | ch <- fmt.Sprintln("Error: ", fields.DbName, "\t export funcs throw, \t", err) 46 | return 47 | } 48 | } 49 | 50 | ch <- fmt.Sprintln("Export ", fields.DbName, "\t success at \t", time.Now().Format("2006-01-02 15:04:05")) 51 | } -------------------------------------------------------------------------------- /bock.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | Bock "./sqlBock/Mysql" 5 | "fmt" 6 | ) 7 | 8 | func main() { 9 | table := Bock.Bock{ 10 | Table: "books", 11 | } 12 | 13 | /*//insert one record 14 | params := make(map[string] interface{}) 15 | args := make(map[string] interface{}) 16 | session := make(map[string] interface{}) 17 | session["userid"] = "112" 18 | args["session"] = session 19 | params["name"] = "golang实战3443" 20 | params["status"] = 0 21 | db := &table 22 | rs := db.Create(params, args) 23 | fmt.Println(rs) 24 | 25 | //update one record 26 | params = make(map[string] interface{}) 27 | args = make(map[string] interface{}) 28 | args["id"] = 2 29 | params["name"] = "update 2" 30 | params["status"] = 3 31 | rs = db.Update(params, args) 32 | fmt.Println(rs) 33 | 34 | //delete one record 35 | args = make(map[string] interface{}) 36 | args["id"] = 6 37 | rs = db.Delete(nil, args) 38 | fmt.Println(rs) 39 | 40 | //execSql 41 | values := make([]interface{}, 0) 42 | values = append(values, "我是手写sql") 43 | values = append(values, 1) 44 | rs = db.ExecSql("update books set name = ? where id = ? ", values) 45 | fmt.Println(rs) 46 | */ 47 | 48 | //insertBatch 49 | vs := make([]map[string]interface{}, 0) 50 | 51 | params := make(map[string] interface{}) 52 | params["name"] = "golang批量11213" 53 | params["isbn"] = "4156s5" 54 | params["status"] = 5 55 | params["id"] = 9 56 | vs = append(vs, params) 57 | 58 | params = make(map[string] interface{}) 59 | params["name"] = "golang批量22af24" 60 | params["isbn"] = "xxfqwt325rqrf45" 61 | params["status"] = 2 62 | params["id"] = 10 63 | vs = append(vs, params) 64 | 65 | db := &table 66 | rs := db.InsertBatch("books", vs) 67 | fmt.Println(rs) 68 | } 69 | -------------------------------------------------------------------------------- /common/Objects.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | type OpFlag struct { 4 | Tables bool 5 | Datum bool 6 | Views bool 7 | Funcs bool 8 | } 9 | 10 | type DbConnFields struct { 11 | DbHost string 12 | DbPort int 13 | DbUser string 14 | DbPass string 15 | DbName string 16 | DbCharset string 17 | FileAlias string 18 | } 19 | 20 | -------------------------------------------------------------------------------- /common/codec.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import ( 4 | "encoding/binary" 5 | "fmt" 6 | ) 7 | 8 | const maxInt32 = 1<<(32-1) - 1 9 | 10 | func writeLen(b []byte, l int) []byte { 11 | if 0 > l || l > maxInt32 { 12 | panic("writeLen: invalid length") 13 | } 14 | var lb [4]byte 15 | binary.BigEndian.PutUint32(lb[:], uint32(l)) 16 | return append(b, lb[:]...) 17 | } 18 | 19 | func readLen(b []byte) ([]byte, int) { 20 | if len(b) < 4 { 21 | panic("readLen: invalid length") 22 | } 23 | l := binary.BigEndian.Uint32(b) 24 | if l > maxInt32 { 25 | panic("readLen: invalid length") 26 | } 27 | return b[4:], int(l) 28 | } 29 | 30 | func Decode(b []byte) []string { 31 | b, ls := readLen(b) 32 | s := make([]string, ls) 33 | for i := range s { 34 | b, ls = readLen(b) 35 | s[i] = string(b[:ls]) 36 | b = b[ls:] 37 | } 38 | return s 39 | } 40 | 41 | func Encode(s []string) []byte { 42 | var b []byte 43 | b = writeLen(b, len(s)) 44 | for _, ss := range s { 45 | b = writeLen(b, len(ss)) 46 | b = append(b, ss...) 47 | } 48 | return b 49 | } 50 | 51 | func codecEqual(s []string) bool { 52 | return fmt.Sprint(s) == fmt.Sprint(Decode(Encode(s))) 53 | } 54 | -------------------------------------------------------------------------------- /common/httpHelper.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import ( 4 | "net/http" 5 | "log" 6 | "io/ioutil" 7 | ) 8 | 9 | func HttpGet(url string) string { 10 | res, err := http.Get(url) 11 | if err != nil { 12 | log.Fatal(err) 13 | } 14 | defer res.Body.Close() 15 | content, err := ioutil.ReadAll(res.Body) 16 | if err != nil { 17 | log.Fatal(err) 18 | } 19 | return string(content) 20 | } 21 | -------------------------------------------------------------------------------- /db/BaseDao.go: -------------------------------------------------------------------------------- 1 | package db 2 | 3 | type BaseDao struct { 4 | Table string 5 | } 6 | 7 | func (b *BaseDao) Retrieve(sql string, values [] interface{}) (map[string]interface{}, error) { 8 | return Query(sql, values) 9 | } -------------------------------------------------------------------------------- /db/Idb.go: -------------------------------------------------------------------------------- 1 | package db 2 | 3 | type Idb interface{ 4 | Retrieve(sql string, valsues [] interface{}) (rs map[string]interface{}, err error) 5 | } 6 | -------------------------------------------------------------------------------- /db/MysqlDao.go: -------------------------------------------------------------------------------- 1 | package db 2 | 3 | import ( 4 | _ "github.com/go-sql-driver/mysql" 5 | mysql "database/sql" 6 | "os" 7 | "encoding/json" 8 | "strconv" 9 | "../common" 10 | ) 11 | 12 | func TestDbConn(fields common.DbConnFields) error { 13 | dao, err := mysql.Open("mysql", fields.DbUser + ":"+fields.DbPass+"@tcp("+fields.DbHost+":"+ 14 | strconv.Itoa(fields.DbPort)+")/"+fields.DbName+"?charset="+fields.DbCharset) 15 | defer dao.Close() 16 | _, err = dao.Prepare("select * from mysql.db ") 17 | return err 18 | } 19 | 20 | func ExecuteWithDbConn(sql string, values []interface{}, fields common.DbConnFields) (map[string]interface{}, error) { 21 | rs := make(map[string]interface{}) 22 | dao, err := mysql.Open("mysql", fields.DbUser + ":"+fields.DbPass+"@tcp("+fields.DbHost+":"+ 23 | strconv.Itoa(fields.DbPort)+")/"+fields.DbName+"?charset="+fields.DbCharset) 24 | defer dao.Close() 25 | if err != nil { 26 | rs["code"] = 204 27 | return rs, err 28 | } 29 | stmt, err := dao.Prepare(sql) 30 | if err != nil { 31 | rs["code"] = 204 32 | return rs, err 33 | } 34 | rows, err := stmt.Query(values...) 35 | if err != nil { 36 | rs["code"] = 204 37 | return rs, err 38 | } 39 | 40 | columns, err := rows.Columns() 41 | vs := make([]mysql.RawBytes, len(columns)) 42 | scans := make([]interface{}, len(columns)) 43 | 44 | for i := range vs { 45 | scans[i] = &vs[i] 46 | } 47 | 48 | var result []map[string]interface{} 49 | for rows.Next() { 50 | _ = rows.Scan(scans...) 51 | each := make(map[string]interface{}) 52 | 53 | for i, col := range vs { 54 | if col != nil { 55 | each[columns[i]] = FilterHolder(string(col)) 56 | }else{ 57 | each[columns[i]] = nil 58 | } 59 | } 60 | 61 | result = append(result, each) 62 | } 63 | rs["code"] = 200 64 | //data, _ := json.Marshal(result) 65 | rs["rows"] = result 66 | return rs, err 67 | } 68 | 69 | func Query(sql string, values []interface{}) (map[string]interface{}, error) { 70 | return execute(sql, values) 71 | } 72 | 73 | func execute(sql string, values []interface{}) (map[string]interface{}, error) { 74 | var configs interface{} 75 | fr, err := os.Open("./configs.json") 76 | decoder := json.NewDecoder(fr) 77 | err = decoder.Decode(&configs) 78 | 79 | confs := configs.(map[string]interface{}) 80 | dialect := confs["database_dialect"].(string) 81 | 82 | dbConf := confs["db_"+dialect+"_config"].(map[string]interface{}) 83 | dbHost := dbConf["db_host"].(string) 84 | dbPort := strconv.FormatFloat(dbConf["db_port"].(float64), 'f', -1, 32) 85 | dbUser := dbConf["db_user"].(string) 86 | dbPass := dbConf["db_pass"].(string) 87 | dbName := dbConf["db_name"].(string) 88 | dbCharset := dbConf["db_charset"].(string) 89 | 90 | rs := make(map[string]interface{}) 91 | dao, err := mysql.Open(dialect, dbUser + ":"+dbPass+"@tcp("+dbHost+":"+dbPort+")/"+dbName+"?charset="+dbCharset) 92 | defer dao.Close() 93 | if err != nil { 94 | rs["code"] = 204 95 | return rs, err 96 | } 97 | stmt, err := dao.Prepare(sql) 98 | if err != nil { 99 | rs["code"] = 204 100 | return rs, err 101 | } 102 | rows, err := stmt.Query(values...) 103 | if err != nil { 104 | rs["code"] = 204 105 | return rs, err 106 | } 107 | 108 | columns, err := rows.Columns() 109 | vs := make([]mysql.RawBytes, len(columns)) 110 | scans := make([]interface{}, len(columns)) 111 | 112 | for i := range vs { 113 | scans[i] = &vs[i] 114 | } 115 | 116 | var result []map[string]string 117 | for rows.Next() { 118 | _ = rows.Scan(scans...) 119 | each := make(map[string]string) 120 | 121 | for i, col := range vs { 122 | each[columns[i]] = FilterHolder(string(col)) 123 | } 124 | 125 | result = append(result, each) 126 | } 127 | rs["code"] = 200 128 | //data, _ := json.Marshal(result) 129 | rs["rows"] = result 130 | return rs, err 131 | } 132 | 133 | func FilterHolder(content string) string { 134 | newContent := "" 135 | for _, value := range content { 136 | if value != 65533 { 137 | newContent += string(value) 138 | } 139 | } 140 | return newContent 141 | } 142 | -------------------------------------------------------------------------------- /demo.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "math" 7 | ) 8 | 9 | func main() { 10 | _, err := IntFromInt64(math.MaxInt32 + 1) 11 | if err != nil { 12 | fmt.Println(err) 13 | } 14 | } 15 | 16 | func ConvertInt64ToInt(i64 int64) int { 17 | if math.MinInt32 <= i64 && i64 <= math.MaxInt32 { 18 | return int(i64) 19 | } 20 | panic("can't convert int64 to int") 21 | } 22 | 23 | func IntFromInt64(i64 int64) (i int, err error) {//这里 24 | defer func() { 25 | if err2 := recover(); err2 != nil { 26 | i = 0//这里 27 | err = errors.New("ttt")//这里 28 | } 29 | }() 30 | i = ConvertInt64ToInt(i64) 31 | return i, nil 32 | } 33 | -------------------------------------------------------------------------------- /ip.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "regexp" 5 | "./common" 6 | "./ipSpider" 7 | "fmt" 8 | ) 9 | 10 | func main() { 11 | ctx := common.HttpGet("http://ipcn.chacuo.net/") 12 | 13 | reg := regexp.MustCompile(`