-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathdb.go
161 lines (142 loc) · 4.56 KB
/
db.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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
package main
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
"github.com/golang-migrate/migrate/v4"
"github.com/golang-migrate/migrate/v4/database/mysql"
_ "github.com/golang-migrate/migrate/v4/database/mysql"
_ "github.com/golang-migrate/migrate/v4/source/file"
_ "github.com/golang-migrate/migrate/v4/source/github"
log "github.com/sirupsen/logrus"
"os"
"time"
)
var dbConnString = os.Getenv("DB_CONNECTION_STRING")
const migrationVer uint = 11
var db *sql.DB
var hystrixDb = "db"
var campStmt *sql.Stmt
var addCampStmt *sql.Stmt
var getUserTagsStmt *sql.Stmt
var getUserExperienceLevelStmt *sql.Stmt
func openDatabaseConnection() (*sql.DB, error) {
conn, err := sql.Open("mysql", dbConnString+"?charset=utf8mb4,utf8")
if err != nil {
return nil, err
}
conn.SetConnMaxLifetime(time.Minute * 3)
conn.SetMaxOpenConns(20)
conn.SetMaxIdleConns(20)
return conn, nil
}
func newMigrate() (*migrate.Migrate, error) {
con, err := openDatabaseConnection()
if err != nil {
log.Fatal("failed to open sql ", err)
}
driver, err := mysql.WithInstance(con, &mysql.Config{})
if err != nil {
log.Fatal("failed to get driver ", err)
}
return migrate.NewWithDatabaseInstance(
getEnv("MIGRATIONS_SOURCE", "file://migrations"),
"mysql", driver)
}
func migrateDatabase() {
log.Info("migrating database")
m, err := newMigrate()
if err != nil {
log.Fatal("failed to connect ", err)
}
defer m.Close()
err = m.Migrate(migrationVer)
if err != nil && err.Error() != "no change" {
log.Fatal("failed to migrate ", err)
}
}
func dropDatabase() {
log.Info("dropping database")
m, err := newMigrate()
if err != nil {
log.Fatal("failed to connect ", err)
}
defer m.Close()
err = m.Drop()
if err != nil && err.Error() != "no change" {
log.Fatal("failed to drop ", err)
}
}
func initializeDatabase() {
var err error
db, err = openDatabaseConnection()
if err != nil {
log.Fatal("failed to open sql ", err)
}
campStmt, err = db.Prepare(`
select id,
title,
url,
image,
ratio,
placeholder,
source,
company,
probability,
fallback,
geo,
tag_relevant_ads.ad_id is not null as is_tag_targeted,
exp_relevant_ads.ad_id is not null as is_exp_targeted
from ads
left join (select ad_id, max(relevant) as relevant
from (select ad_id,
exists (select user_id
from user_tags
where user_tags.tag = ad_tags.tag
and user_tags.user_id = ?) as relevant
from ad_tags) as res
group by ad_id) tag_relevant_ads on ads.id = tag_relevant_ads.ad_id
left join (select ad_id, max(relevant) as relevant
from (select ad_id,
exists (select user_id
from user_experience_levels
where user_experience_levels.experience_level = ad_experience_level.experience_level
and user_experience_levels.user_id = ?) as relevant
from ad_experience_level) as res
group by ad_id) exp_relevant_ads on ads.id = exp_relevant_ads.ad_id
where start <= ? and end > ? and
(
(tag_relevant_ads.relevant = 1 and exp_relevant_ads.relevant = 1)
or
(tag_relevant_ads.relevant is null and exp_relevant_ads.relevant is null)
or
(tag_relevant_ads.relevant = 1 and exp_relevant_ads.relevant is null)
or
(tag_relevant_ads.relevant is null and exp_relevant_ads.relevant = 1)
)`)
if err != nil {
log.Fatal("failed to prepare query ", err)
}
addCampStmt, err = db.Prepare(
"insert into `ads` " +
"(`id`, `title`, `url`, `image`, `ratio`, `placeholder`, `source`, " +
"`company`, `probability`, `fallback`, `geo`, `start`, `end`) " +
"values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
if err != nil {
log.Fatal("failed to prepare query ", err)
}
getUserTagsStmt, err = db.Prepare("select tag from user_tags where user_id = ? order by last_read desc limit 50")
if err != nil {
log.Fatal("failed to prepare query ", err)
}
getUserExperienceLevelStmt, err = db.Prepare("select experience_level from user_experience_levels where user_id = ?")
if err != nil {
log.Fatal("failed to prepare query ", err)
}
}
func tearDatabase() {
addCampStmt.Close()
campStmt.Close()
getUserTagsStmt.Close()
getUserExperienceLevelStmt.Close()
db.Close()
}