-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
124 lines (110 loc) · 3.32 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package main
import (
"fmt"
"log"
"os"
_ "github.com/mattn/go-sqlite3"
"github.com/Masterminds/squirrel"
"github.com/jmoiron/sqlx"
"gopkg.in/alecthomas/kingpin.v2"
)
// CountBuilder is a squirrel select builder whose columns match Count fields.
var CountBuilder = squirrel.Select().
Column(squirrel.Alias(squirrel.Expr("CASE WHEN rname IS NULL THEN \"\" ELSE rname END"), "rname")).
Column(squirrel.Alias(squirrel.Expr("CASE WHEN strand IS NULL THEN 0 ELSE strand END"), "strand")).
Column(squirrel.Alias(squirrel.Expr("COUNT(*)"), "count")).
Column(squirrel.Alias(squirrel.Expr("CAST(TOTAL(copy_number) AS INTEGER)"), "copyNum"))
// Count is a databases row with record count information.
type Count struct {
Chrom string `db:"rname"`
Ori int `db:"strand"`
Count int `db:"count"`
CopyNum int `db:"copyNum"`
}
const prog = "htsdb-count-reads"
const version = "0.4"
const descr = `Print the number of reads and read copies stored in the
database. Supports grouping by reference, orientation or both. Provided SQL
filter will apply to all counts.`
var (
app = kingpin.New(prog, descr)
dbFile = app.Flag("db", "File to SQLite database.").
PlaceHolder("<file>").Required().String()
tab = app.Flag("table", "Database table name.").
Default("sample").String()
where = app.Flag("where", "SQL filter to inject in WHERE clause.").
PlaceHolder("<SQL>").String()
as = app.Flag("as", "Name to print describing the count/s.").
Default("all").String()
header = app.Flag("header", "Print header line.").
Bool()
groupByChrom = app.Flag("by-ref", "Group counts by reference.").
Bool()
groupByOri = app.Flag("by-ori", "Group counts by orientation.").
Bool()
)
func main() {
// read command line args and options
app.HelpFlag.Short('h')
app.Version(version)
_, err := app.Parse(os.Args[1:])
if err != nil {
kingpin.Fatalf("%s", err)
}
// assemble sqlx select builders
countBuilder := CountBuilder.From(*tab)
if *where != "" {
countBuilder = countBuilder.Where(*where)
}
if *groupByChrom == true {
countBuilder = countBuilder.GroupBy("rname")
}
if *groupByOri == true {
countBuilder = countBuilder.GroupBy("strand")
}
// open database connections.
var db *sqlx.DB
if db, err = sqlx.Connect("sqlite3", *dbFile); err != nil {
log.Fatal(err)
}
// prepare statements.
query, _, err := countBuilder.ToSql()
if err != nil {
log.Fatal(err)
}
// get the count
var counts []Count
if err = db.Select(&counts, query); err != nil {
log.Fatal(err)
}
// print results.
if *groupByChrom == true && *groupByOri == true {
if *header == true {
fmt.Printf("category\tref\tori\tcount\tcopyNumber\n")
}
for _, c := range counts {
fmt.Printf("%s\t%s\t%d\t%d\t%d\n", *as, c.Chrom, c.Ori, c.Count, c.CopyNum)
}
} else if *groupByChrom == true {
if *header == true {
fmt.Printf("category\tref\tcount\tcopyNumber\n")
}
for _, c := range counts {
fmt.Printf("%s\t%s\t%d\t%d\n", *as, c.Chrom, c.Count, c.CopyNum)
}
} else if *groupByOri == true {
if *header == true {
fmt.Printf("category\tori\tcount\tcopyNumber\n")
}
for _, c := range counts {
fmt.Printf("%s\t%d\t%d\t%d\n", *as, c.Ori, c.Count, c.CopyNum)
}
} else {
if *header == true {
fmt.Printf("category\tcount\tcopyNumber\n")
}
for _, c := range counts {
fmt.Printf("%s\t%d\t%d\n", *as, c.Count, c.CopyNum)
}
}
}