8 def createPropertiesTable(conn
, propdef
):
9 conn
.execute("BEGIN EXCLUSIVE")
12 c
.execute("SELECT count(name) FROM sqlite_master WHERE name='properties';")
13 if c
.fetchone() == (0,):
14 print("Creating properties table.")
15 sqlstmt
= "CREATE TABLE properties (jobid INTEGER PRIMARY KEY, %s, \
16 FOREIGN KEY (jobid) REFERENCES jobs (id));" % (propdef
,)
21 proc
= subprocess
.Popen(cmd
, \
22 stdout
=subprocess
.PIPE
, stderr
=subprocess
.PIPE
, shell
=True)
23 out
, err
= proc
.communicate()
24 exitcode
= proc
.wait()
25 return exitcode
, out
, err
27 def processJob(conn
, jobid
):
28 print("Process job %d" % (jobid
))
31 c
.execute("SELECT cmd FROM jobs WHERE id=?", (jobid
,))
34 ec
, out
, err
= runCmd(cmd
)
35 c
.execute("UPDATE jobs SET exitcode=?, done=1 WHERE id=?;", (ec
, jobid
))
38 for l
in out
.splitlines():
39 if l
.startswith("DB-PROPERTIES:"):
41 for l
in err
.splitlines():
42 if l
.startswith("DB-PROPERTIES:"):
48 for k
, v
in p
.iteritems():
52 collist
= ", ".join([str(k
) for k
in prop
.keys()])
53 collist
= "jobid, " + collist
55 vallist
= ", ".join(["?" for k
in prop
.keys()])
56 vallist
= "?, " + vallist
59 sqlstmt
= "INSERT INTO properties (%s) VALUES (%s);" % (collist
,vallist
)
60 c
.execute(sqlstmt
, [jobid
] + list(prop
.values()))
64 def insertJobs(conn
, cmds
):
65 conn
.execute("BEGIN EXCLUSIVE")
66 conn
.executemany("INSERT INTO jobs (cmd) VALUES (?);", cmds
)
69 def createSchema(conn
):
72 c
.execute("BEGIN EXCLUSIVE")
74 # Create table, if necessary
75 c
.execute("SELECT count(name) FROM sqlite_master WHERE name='jobs';")
76 if c
.fetchone() == (0,):
77 print("Creating jobs table.")
78 conn
.execute("CREATE TABLE jobs ( \
79 id INTEGER PRIMARY KEY AUTOINCREMENT, \
80 cmd STRING NOT NULL, \
81 started BOOL DEFAULT (0) NOT NULL, \
82 done BOOL DEFAULT (0) NOT NULL, \
86 def getNextJobId(conn
):
89 c
.execute("BEGIN EXCLUSIVE")
90 c
.execute("SELECT id FROM jobs WHERE NOT started=1 LIMIT 1;")
97 conn
.execute("UPDATE jobs SET started=1 WHERE id=?;", (jobid
,))
105 """Print usage text of this program"""
108 Take the jobs defined in jobs table of given database and process one job after
109 the other. Multiple instances may be launched against the same database.
111 A list of jobs may be importet line-by-line from a file using the -c option.
112 Every job may output to stdout or stderr a string of the form
113 DB-PROPERTIES: {{ "key": "value", "key2": 1.23, "key3": True}}
114 It is assumed that a table 'properties' exists with the columns jobid, key,
115 key2, and key3. The corresponding values are inserted into this table. Using
116 the option -p such a properties table can be created by giving a list of
117 column definitions in SQL style.
120 {0} [OPTIONS] -d database
124 -c cmdfn add jobs from the file with list of commands
125 -d database the database to process
127 -p cols-def create properties table with SQL column spec
130 {0} -d stats.db -c cmds.sh -p 'time REAL, mem INTEGER'
131 """.format(sys
.argv
[0]))
134 if __name__
== "__main__":
142 opts
, args
= getopt
.getopt(sys
.argv
[1:], "hd:c:p:")
144 for opt
, arg
in opts
:
155 print("Unknown option '", opt
, "'.")
157 except getopt
.GetoptError
as e
:
158 print("Error parsing arguments:", e
)
160 sys
.exit(os
.EX_USAGE
)
163 print("No database given.")
164 sys
.exit(os
.EX_USAGE
)
167 conn
= sqlite3
.connect(dbfn
)
171 createPropertiesTable(conn
, propdef
)
174 print("Adding jobs...")
175 cmds
= open(cmdfn
).readlines()
176 cmds
= [(c
.strip(),) for c
in cmds
]
177 insertJobs(conn
, cmds
)
180 jobid
= getNextJobId(conn
)
182 print("All jobs have been started.")
184 processJob(conn
, jobid
)