]> git.donarmstrong.com Git - cran2deb.git/blob - branch/multisys/R/db.R
multisys: support for multiple os-arch configurations (preliminary)
[cran2deb.git] / branch / multisys / R / db.R
1
2 db_start <- function() {
3     drv <- dbDriver('SQLite')
4     con <- dbConnect(drv, dbname=file.path(cache_root,'cran2deb.db'))
5     if (!dbExistsTable(con,'sysreq_override')) {
6         dbGetQuery(con,paste('CREATE TABLE sysreq_override ('
7                   ,' depend_alias TEXT NOT NULL'
8                   ,',r_pattern TEXT PRIMARY KEY NOT NULL'
9                   ,')'))
10     }
11     if (!dbExistsTable(con,'debian_dependency')) {
12         dbGetQuery(con,paste('CREATE TABLE debian_dependency ('
13                   ,' id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL'
14                   ,',alias TEXT NOT NULL'
15                   ,',build INTEGER NOT NULL'
16                   ,',debian_pkg TEXT NOT NULL'
17                   ,',UNIQUE (alias,build,debian_pkg)'
18                   ,')'))
19     }
20     if (!dbExistsTable(con,'forced_depends')) {
21         dbGetQuery(con,paste('CREATE TABLE forced_depends ('
22                   ,' r_name TEXT NOT NULL'
23                   ,',depend_alias TEXT NOT NULL'
24                   ,',PRIMARY KEY (r_name,depend_alias)'
25                   ,')'))
26     }
27     if (!dbExistsTable(con,'license_override')) {
28         dbGetQuery(con,paste('CREATE TABLE license_override ('
29                   ,' name TEXT PRIMARY KEY NOT NULL'
30                   ,',accept INT NOT NULL'
31                   ,')'))
32     }
33     if (!dbExistsTable(con,'license_hashes')) {
34         dbGetQuery(con,paste('CREATE TABLE license_hashes ('
35                   ,' name TEXT NOT NULL'
36                   ,',sha1 TEXT PRIMARY KEY NOT NULL'
37                   ,')'))
38     }
39     if (!dbExistsTable(con,'database_versions')) {
40         dbGetQuery(con,paste('CREATE TABLE database_versions ('
41                   ,' version INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL'
42                   ,',version_date INTEGER NOT NULL'
43                   ,',base_epoch INTEGER NOT NULL'
44                   ,')'))
45         db_add_version(con,1,0)
46     }
47     if (!dbExistsTable(con,'packages')) {
48         dbGetQuery(con,paste('CREATE TABLE packages ('
49                   ,' package TEXT PRIMARY KEY NOT NULL'
50                   ,',latest_r_version TEXT'
51                   ,')'))
52     }
53     if (!dbExistsTable(con,'builds')) {
54         dbGetQuery(con,paste('CREATE TABLE builds ('
55                   ,' id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL'
56                   ,',package TEXT NOT NULL'
57                   ,',r_version TEXT NOT NULL'
58                   ,',deb_epoch INTEGER NOT NULL'
59                   ,',deb_revision INTEGER NOT NULL'
60                   ,',db_version INTEGER NOT NULL'
61                   ,',date_stamp TEXT NOT NULL'
62                   ,',git_revision TEXT NOT NULL'  # legacy: really scm_revision
63                   ,',success INTEGER NOT NULL'
64                   ,',log TEXT'
65                   ,',UNIQUE(package,r_version,deb_epoch,deb_revision,db_version)'
66                   ,')'))
67     }
68     return(con)
69 }
70
71 db_stop <- function(con,bump=F) {
72     if (bump) {
73         db_bump(con)
74     }
75     dbDisconnect(con)
76 }
77
78 db_quote <- function(text) {
79     return(paste('\'', gsub('([\'"])','\\1\\1',text),'\'',sep=''))
80 }
81
82 db_now <- function() {
83     return(as.integer(gsub('-','',Sys.Date())))
84 }
85
86 db_cur_version <- function(con) {
87     return(as.integer(dbGetQuery(con, 'SELECT max(version) FROM database_versions')[[1]]))
88 }
89
90 db_base_epoch <- function(con) {
91     return(as.integer(dbGetQuery(con,
92         paste('SELECT max(base_epoch) FROM database_versions'
93              ,'WHERE version IN (SELECT max(version) FROM database_versions)'))[[1]]))
94 }
95
96 db_get_base_epoch <- function() {
97     con <- db_start()
98     v <- db_base_epoch(con)
99     db_stop(con)
100     return(v)
101 }
102
103 db_get_version <- function() {
104     con <- db_start()
105     v <- db_cur_version(con)
106     db_stop(con)
107     return(v)
108 }
109
110 db_add_version <- function(con, version, epoch) {
111     dbGetQuery(con,paste('INSERT INTO database_versions (version,version_date,base_epoch)'
112               ,'VALUES (',as.integer(version),',',db_now(),',',as.integer(epoch),')'))
113 }
114
115 db_bump <- function(con) {
116     db_add_version(con,db_cur_version(con)+1, db_base_epoch(con))
117 }
118
119 db_bump_epoch <- function(con) {
120     db_add_version(con,db_cur_version(con)+1, db_base_epoch(con)+1)
121 }
122
123 db_sysreq_override <- function(sysreq_text) {
124     con <- db_start()
125     results <- dbGetQuery(con,paste(
126                     'SELECT DISTINCT depend_alias FROM sysreq_override WHERE'
127                             ,db_quote(tolower(sysreq_text)),'LIKE r_pattern'))
128     db_stop(con)
129     if (length(results) == 0) {
130         return(NULL)
131     }
132     return(results$depend_alias)
133 }
134
135 db_add_sysreq_override <- function(pattern,depend_alias) {
136     con <- db_start()
137     results <- dbGetQuery(con,paste(
138                      'INSERT OR REPLACE INTO sysreq_override'
139                     ,'(depend_alias, r_pattern) VALUES ('
140                     ,' ',db_quote(tolower(depend_alias))
141                     ,',',db_quote(tolower(pattern))
142                     ,')'))
143     db_stop(con,TRUE)
144 }
145
146 db_sysreq_overrides <- function() {
147     con <- db_start()
148     overrides <- dbGetQuery(con,paste('SELECT * FROM sysreq_override'))
149     db_stop(con)
150     return(overrides)
151 }
152
153 db_get_depends <- function(depend_alias,build=F) {
154     con <- db_start()
155     results <- dbGetQuery(con,paste(
156                     'SELECT DISTINCT debian_pkg FROM debian_dependency WHERE'
157                     ,db_quote(tolower(depend_alias)),'= alias'
158                     ,'AND',as.integer(build),'= build'))
159     db_stop(con)
160     return(results$debian_pkg)
161 }
162
163 db_add_depends <- function(depend_alias,debian_pkg,build=F) {
164     con <- db_start()
165     results <- dbGetQuery(con,paste(
166                      'INSERT OR REPLACE INTO debian_dependency'
167                     ,'(alias, build, debian_pkg) VALUES ('
168                     ,' ',db_quote(tolower(depend_alias))
169                     ,',',as.integer(build)
170                     ,',',db_quote(tolower(debian_pkg))
171                     ,')'))
172     db_stop(con,TRUE)
173 }
174
175 db_depends <- function() {
176     con <- db_start()
177     depends <- dbGetQuery(con,paste('SELECT * FROM debian_dependency'))
178     db_stop(con)
179     return(depends)
180 }
181
182 db_get_forced_depends <- function(r_name) {
183     con <- db_start()
184     forced_depends <- dbGetQuery(con,
185                 paste('SELECT depend_alias FROM forced_depends WHERE'
186                      ,db_quote(r_name),'= r_name'))
187     db_stop(con)
188     return(forced_depends$depend_alias)
189 }
190
191 db_add_forced_depends <- function(r_name, depend_alias) {
192     if (!length(db_get_depends(depend_alias,build=F)) &&
193         !length(db_get_depends(depend_alias,build=T))) {
194         fail('Debian dependency alias',depend_alias,'is not know,'
195                   ,'yet trying to force a dependency on it?')
196     }
197     con <- db_start()
198     dbGetQuery(con,
199             paste('INSERT OR REPLACE INTO forced_depends (r_name, depend_alias)'
200                  ,'VALUES (',db_quote(r_name),',',db_quote(depend_alias),')'))
201     db_stop(con,TRUE)
202 }
203
204 db_forced_depends <- function() {
205     con <- db_start()
206     depends <- dbGetQuery(con,paste('SELECT * FROM forced_depends'))
207     db_stop(con)
208     return(depends)
209 }
210
211 db_license_override_name <- function(name) {
212     con <- db_start()
213     results <- dbGetQuery(con,paste(
214                     'SELECT DISTINCT accept FROM license_override WHERE'
215                             ,db_quote(tolower(name)),'= name'))
216     db_stop(con)
217     if (length(results) == 0) {
218         return(NULL)
219     }
220     return(as.logical(results$accept))
221 }
222
223 db_add_license_override <- function(name,accept) {
224     notice('adding',name,'accept?',accept)
225     if (accept != TRUE && accept != FALSE) {
226         fail('accept must be TRUE or FALSE')
227     }
228     con <- db_start()
229     results <- dbGetQuery(con,paste(
230                      'INSERT OR REPLACE INTO license_override'
231                     ,'(name, accept) VALUES ('
232                     ,' ',db_quote(tolower(name))
233                     ,',',as.integer(accept)
234                     ,')'))
235     db_stop(con,TRUE)
236 }
237
238 db_license_override_hash <- function(license_sha1) {
239     con <- db_start()
240     results <- dbGetQuery(con,paste(
241                      'SELECT DISTINCT accept FROM license_override'
242                     ,'INNER JOIN license_hashes'
243                     ,'ON license_hashes.name = license_override.name WHERE'
244                     ,db_quote(tolower(license_sha1)),'= license_hashes.sha1'))
245     db_stop(con)
246     if (length(results) == 0) {
247         return(NULL)
248     }
249     return(as.logical(results$accept))
250 }
251
252 db_license_overrides <- function() {
253     con <- db_start()
254     overrides <- dbGetQuery(con,paste('SELECT * FROM license_override'))
255     hashes    <- dbGetQuery(con,paste('SELECT * FROM license_hashes'))
256     db_stop(con)
257     return(list(overrides=overrides,hashes=hashes))
258 }
259
260 db_add_license_hash <- function(name,license_sha1) {
261     if (is.null(db_license_override_name(name))) {
262         fail('license',name,'is not know, yet trying to add a hash for it?')
263     }
264     notice('adding hash',license_sha1,'for',name)
265     con <- db_start()
266     dbGetQuery(con,paste(
267          'INSERT OR REPLACE INTO license_hashes'
268         ,'(name, sha1) VALUES ('
269         ,' ',db_quote(tolower(name))
270         ,',',db_quote(tolower(license_sha1))
271         ,')'))
272     db_stop(con,TRUE)
273 }
274
275
276 db_update_package_versions <- function() {
277     con <- db_start()
278     for (package in available[,'Package']) {
279         dbGetQuery(con, paste('INSERT OR REPLACE INTO packages (package,latest_r_version)'
280                              ,'VALUES (',db_quote(package)
281                              ,',',db_quote(available[package,'Version']),')'))
282     }
283     db_stop(con)
284 }
285
286 db_record_build <- function(package, deb_version, log, success=F) {
287     con <- db_start()
288     dbGetQuery(con,paste('INSERT OR REPLACE INTO builds'
289                         ,'(package,r_version,deb_epoch,deb_revision,db_version,success,date_stamp,git_revision,log)'
290                         ,'VALUES'
291                         ,'(',db_quote(package)
292                         ,',',db_quote(version_upstream(deb_version))
293                         ,',',db_quote(version_epoch(deb_version))
294                         ,',',db_quote(version_revision(deb_version))
295                         ,',',db_cur_version(con)
296                         ,',',as.integer(success)
297                         ,',',db_quote(format(Sys.time(),'%a, %d %b %Y %H:%M:%S %z'))
298                         ,',',db_quote(scm_revision)
299                         ,',',db_quote(paste(log, collapse='\n'))
300                         ,')'))
301     db_stop(con)
302 }
303
304 db_builds <- function(pkgname) {
305     # returns all successful builds
306     con <- db_start()
307     build <- dbGetQuery(con, paste('SELECT * FROM builds'
308                        ,'WHERE success = 1'
309                        ,'AND package =',db_quote(pkgname)))
310     db_stop(con)
311     if (length(build) == 0) {
312         return(NULL)
313     }
314     build$success <- as.logical(build$success)
315     return(build)
316 }
317
318 db_latest_build <- function(pkgname) {
319     con <- db_start()
320     build <- dbGetQuery(con, paste('SELECT * FROM builds'
321                        ,'NATURAL JOIN (SELECT package,max(id) AS max_id FROM builds'
322                        ,              'GROUP BY package) AS last'
323                        ,'WHERE id = max_id'
324                        ,'AND builds.package =',db_quote(pkgname)))
325     db_stop(con)
326     if (length(build) == 0) {
327         return(NULL)
328     }
329     build$success <- as.logical(build$success)
330     return(build)
331 }
332
333 db_latest_build_version <- function(pkgname) {
334     build <- db_latest_build(pkgname)
335     if (is.null(build)) {
336         return(NULL)
337     }
338     return(version_new(build$r_version, build$deb_revision, build$deb_epoch))
339 }
340
341 db_latest_build_status <- function(pkgname) {
342     build <- db_latest_build(pkgname)
343     if (is.null(build)) {
344         return(NULL)
345     }
346     return(list(build$success,build$log))
347 }
348
349 db_outdated_packages <- function() {
350     con <- db_start()
351     packages <- dbGetQuery(con,paste('SELECT packages.package FROM packages'
352                ,'LEFT OUTER JOIN ('
353                # extract the latest attempt at building each package
354                ,      'SELECT * FROM builds'
355                ,      'NATURAL JOIN (SELECT package,max(id) AS max_id FROM builds'
356                ,                    'GROUP BY package) AS last'
357                ,      'WHERE id = max_id) AS build'
358                ,'ON build.package = packages.package'
359                # outdated iff:
360                # - there is no latest build
361                ,'WHERE build.package IS NULL'
362                # - the database has changed since last build
363                ,'OR build.db_version < (SELECT max(version) FROM database_versions)'
364                # - the debian epoch has been bumped up
365                ,'OR build.deb_epoch < (SELECT max(base_epoch) FROM database_versions'
366                ,                        'WHERE version IN ('
367                ,                            'SELECT max(version) FROM database_versions))'
368                # - the latest build is not of the latest R version
369                ,'OR build.r_version != packages.latest_r_version'
370                ))$package
371     db_stop(con)
372     return(packages)
373 }
374