// 从存档读取上市公司列表 func (l *CompanyList) Load(market Market) error { lines, err := io.ReadLines(filepath.Join(config.Get().DataDir, market.Name(), companiesFileName)) if err != nil { return err } companies := make([]Company, 0) for _, line := range lines { parts := strings.Split(line, "\t") if len(parts) != 2 { return fmt.Errorf("[%s]\t上市公司文件格式有错误: %s", market.Name(), line) } companies = append(companies, Company{ Market: market.Name(), Code: parts[0], Name: parts[1]}) } cl := CompanyList(companies) l = &cl return nil }
// 启动服务 func Start() { e := echo.New() // Middleware // e.Use(mw.Logger()) e.Use(mw.Recover()) e.Use(mw.Gzip()) // 注册路由 registerRoute(e) log.Printf("启动Http服务,端口:%d", config.Get().Port) // Start server e.Run(fmt.Sprintf(":%d", config.Get().Port)) }
// 保存上市公司列表到文件 func (l CompanyList) Save(market Market) error { lines := make([]string, 0) companies := ([]Company)(l) for _, company := range companies { lines = append(lines, fmt.Sprintf("%s\t%s", company.Code, company.Name)) } return io.WriteLines(filepath.Join(config.Get().DataDir, market.Name(), companiesFileName), lines) }
// 获取数据库连接 func Get() (*mgo.Session, error) { if startSession == nil { session, err := mgo.DialWithTimeout(config.Get().MongoUrl, time.Minute) if err != nil { return nil, err } startSession = session } return startSession.Clone(), nil }
// 获取所有待处理的文件 func getAllRawFiles() ([]string, error) { files := make([]string, 0) // 遍历目录 err := filepath.Walk(config.Get().DataDir, func(path string, info os.FileInfo, err error) error { // 过滤原始数据文件 if strings.HasSuffix(path, "_raw.txt") { files = append(files, path) } return err }) return files, err }
// 获取数据库连接 func getDB(market Market, code string) (*sql.DB, error) { filePath := filepath.Join(config.Get().DataDir, market.Name(), strings.ToLower(code)+".db") db, err := sql.Open("sqlite3", filePath) if err != nil { return nil, err } // 确保数据表都存在 err = ensureTables(db) if err != nil { return nil, err } return db, nil }
// 从文件名中获取信息 func retrieveParams(path string) (string, string, time.Time, error) { other := strings.Replace(path, config.Get().DataDir, "", -1) // 路径处理 if os.IsPathSeparator(other[0]) { other = other[1:] } parts := strings.Split(other, string(os.PathSeparator)) if len(parts) != 3 { return "", "", time.Now(), fmt.Errorf("[分析]\t不规则的文件名:%s", path) } day, err := time.Parse("20060102", strings.Replace(parts[2], "_raw.txt", "", -1)) if err != nil { return "", "", time.Now(), fmt.Errorf("[分析]\t不规则的文件名:%s", path) } return parts[0], parts[1], day, nil }
// 从文件读取分时数据 func loadPeroid(market Market, code string, start, end time.Time, table string) ([]Peroid60, error) { filePath := filepath.Join(config.Get().DataDir, market.Name(), strings.ToLower(code)+".db") db, err := sql.Open("sqlite3", filePath) if err != nil { return nil, err } defer db.Close() stmt, err := db.Prepare("select time, open, close, high, low, volume from " + table + " where time >= ? and time <= ? order by time") if err != nil { return nil, err } defer stmt.Close() // 查询 row, err := stmt.Query(start, end) if err != nil { return nil, err } defer row.Close() var _time time.Time var open, _close, high, low float32 var volume int64 peroids := make([]Peroid60, 0) for row.Next() { err = row.Scan(&_time, &open, &_close, &high, &low, &volume) if err != nil { return nil, err } peroids = append(peroids, Peroid60{market.Name(), code, _time, open, _close, high, low, volume}) } return peroids, nil }
// 打开日志文件 func openLogFile() (*os.File, error) { // 日志文件路径 logPath := filepath.Join(config.Get().RootDir, logFileName) return os.OpenFile(logPath, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0660) }