main.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. // 数据统计
  2. package main
  3. import (
  4. "encoding/csv"
  5. "flag"
  6. "os"
  7. "sort"
  8. "strconv"
  9. "database/sql"
  10. "log"
  11. _ "github.com/mattn/go-sqlite3"
  12. )
  13. type (
  14. Folder struct {
  15. Id int
  16. Name string
  17. ParentName string
  18. ParentParentName string
  19. ParentId int
  20. Count int
  21. }
  22. Cities []*Folder
  23. )
  24. var (
  25. dbfile = flag.String("db", "/Users/taozhang/Downloads/cloudreve.db", "数据文件")
  26. outfile = flag.String("of", "./结果.csv", "结果输出文件")
  27. db *sql.DB
  28. )
  29. // init
  30. func init() {
  31. flag.Parse()
  32. var err error
  33. db, err = sql.Open("sqlite3", *dbfile)
  34. if err != nil {
  35. log.Fatal(err)
  36. }
  37. }
  38. func main() {
  39. defer db.Close()
  40. // 执行查询,加载目录
  41. rows, err := db.Query("SELECT id, name,parent_id FROM folders")
  42. if err != nil {
  43. log.Fatal(err)
  44. }
  45. allCities := map[int]*Folder{}
  46. // 先拿到所有目录
  47. for rows.Next() {
  48. var id, _pid int
  49. var parentId sql.NullInt32
  50. var name string
  51. err := rows.Scan(&id, &name, &parentId)
  52. if err != nil {
  53. log.Fatal(err)
  54. }
  55. _pid = int(parentId.Int32)
  56. allCities[id] = &Folder{
  57. Id: id,
  58. Name: name,
  59. ParentId: _pid,
  60. }
  61. }
  62. rows.Close()
  63. //TODO 需要筛选的目录,只筛选政府类的市,但是要补上父级,爷爷级节点名称,便于统计
  64. selectCities := map[int]*Folder{}
  65. for _, v := range allCities {
  66. if v.Name == "政府" {
  67. if pv, ok := allCities[v.ParentId]; ok {
  68. //给pv也补上父级关系
  69. if ppv, ok := allCities[pv.ParentId]; ok {
  70. pv.ParentName = ppv.Name
  71. //补上爷爷级节点
  72. if pppv, ok := allCities[ppv.ParentId]; ok {
  73. pv.ParentParentName = pppv.Name
  74. }
  75. }
  76. selectCities[v.Id] = pv
  77. }
  78. }
  79. }
  80. //TODO 计算所有目录的文件数量
  81. rows, err = db.Query("select folder_id,count(id) as fs from files group by folder_id;")
  82. if err != nil {
  83. log.Fatal(err)
  84. }
  85. selectCitiesArray := make(Cities, 0, 0)
  86. for rows.Next() {
  87. var id int
  88. var filesCount int
  89. err := rows.Scan(&id, &filesCount)
  90. if err != nil {
  91. log.Fatal(err)
  92. }
  93. if v, ok := selectCities[id]; ok {
  94. v.Count = filesCount
  95. selectCitiesArray = append(selectCitiesArray, v)
  96. }
  97. }
  98. rows.Close()
  99. //TODO 正向排序
  100. sort.Slice(selectCitiesArray, func(i, j int) bool { return selectCitiesArray[i].Count < selectCitiesArray[j].Count })
  101. //TODO 结果输出到CSV文件
  102. fo, err := os.Create(*outfile)
  103. if err != nil {
  104. log.Fatal(err)
  105. }
  106. writer := csv.NewWriter(fo)
  107. writer.Write([]string{"年", "省", "城市", "组合筛选KEY", "文件数"})
  108. for _, v := range selectCitiesArray {
  109. writer.Write([]string{v.ParentParentName, v.ParentName, v.Name,
  110. v.ParentParentName + v.ParentName + v.Name, strconv.Itoa(v.Count)})
  111. log.Println(v.Id, v.ParentParentName, v.ParentName, v.Name, v.Count)
  112. }
  113. writer.Flush()
  114. fo.Close()
  115. }