1
2 """
3 HQL plugin
4
5 Plugin read by omero.cli.Cli during initialization. The method(s)
6 defined here will be added to the Cli class for later use.
7
8 Copyright 2008 Glencoe Software, Inc. All rights reserved.
9 Use is subject to license terms supplied in LICENSE.txt
10
11 """
12
13 from omero.cli import BaseControl, CLI
14 import exceptions
15 import cmd
16 import time
17 import cmd
18 import sys
19
20 HELP = """Executes an HQL statement with the given parameters.
21 If no query is given, then a shell is opened which
22 will run any entered query with the current parameters."""
23
25
33
35 if args.query:
36 self.hql(args)
37 else:
38 if args.quiet:
39 self.ctx.die(67, "Can't ask for query with --quiet option")
40 while True:
41 args.query = self.ctx.input("Enter query:")
42 if not args.query:
43 break
44 if not self.hql(args, loop = True):
45 break
46
47 - def hql(self, args, loop = False):
48 from omero_sys_ParametersI import ParametersI
49
50 ice_map = dict()
51 if args.admin:
52 ice_map["omero.group"]="-1"
53
54 c = self.ctx.conn(args)
55 q = c.sf.getQueryService()
56 p = ParametersI()
57 p.page(args.offset, args.limit)
58 rv = self.project(q, args.query, p, ice_map)
59 has_details = self.display(rv)
60 if args.quiet:
61 return
62
63 input = """
64 To see details for object, enter line number.
65 To move ahead one page, enter 'p'
66 To re-display list, enter 'r'.
67 To quit, enter 'q' or just enter.
68 """
69 if loop:
70 input = input + """To run another query, press enter\n"""
71
72 while True:
73 id = self.ctx.input(input)
74 id = id.lower()
75
76
77 if not id:
78 return True
79 if id.startswith("q"):
80 return False
81
82
83 if id.startswith("p"):
84 p.page(p.getOffset().val + p.getLimit().val, p.getLimit())
85 self.ctx.dbg("\nCurrent page: offset=%s, limit=%s\n" % (p.theFilter.offset.val, p.theFilter.limit.val))
86 rv = self.project(q, args.query, p, ice_map)
87 self.display(rv)
88 elif id.startswith("r"):
89 self.display(rv)
90 else:
91 try:
92 id = long(id)
93 obj = rv[id]
94 if id not in has_details:
95 self.ctx.out("No details available: %s" % id)
96 continue
97 else:
98 obj = obj[0].val
99 except:
100 self.ctx.out("Invalid choice: %s" % id)
101 continue
102 keys = sorted(obj.__dict__)
103 keys.remove("_id")
104 keys.remove("_details")
105 self.ctx.out("id = %s" % obj.id.val)
106 for key in keys:
107 value = self.unwrap(obj.__dict__[key])
108 if isinstance(value, (str, unicode)):
109 value = "'%s'" % value
110 if key.startswith("_"):
111 key = key[1:]
112 self.ctx.out("%s = %s" % (key, value))
113 continue
114
115 - def display(self, rv, cols = None):
116 import omero_model_Details_ice
117 import omero_model_IObject_ice
118 import omero.rtypes
119 from omero.model import IObject
120 from omero.model import Details
121 from omero.util.text import TableBuilder
122
123 has_details = []
124 tb = TableBuilder("#")
125 for idx, object_list in enumerate(rv):
126 klass = "Null"
127 id = ""
128 values = {}
129
130 if len(object_list) == 1 and isinstance(object_list[0], omero.rtypes.RObjectI):
131 has_details.append(idx)
132 o = object_list[0].val
133 if o:
134 tb.cols(["Class", "Id"])
135 klass = o.__class__.__name__
136 id = o.id.val
137 for k, v in o.__dict__.items():
138 values[k] = self.unwrap(v)
139 values = self.filter(values)
140 tb.cols(values.keys())
141 tb.row(idx, klass, id, **values)
142
143 else:
144 indices = range(1, len(object_list) + 1)
145 if cols is not None:
146 tb.cols(cols)
147 else:
148 tb.cols(["Col%s" % x for x in indices])
149 values = tuple([self.unwrap(x) for x in object_list])
150 tb.row(idx, *values)
151 self.ctx.out(str(tb.build()))
152 return has_details
153
154 - def unwrap(self, object, cache = None):
155
156 if cache == None:
157 cache = {}
158 elif object in cache:
159 return cache[id(object)]
160
161 from omero.rtypes import unwrap
162 import omero_model_Details_ice
163 import omero_model_IObject_ice
164 from omero.model import IObject
165 from omero.model import Details
166 from omero.rtypes import RObjectI
167 from omero.rtypes import RTimeI
168
169
170
171
172 unwrapped = unwrap(object, cache)
173 if isinstance(unwrapped, IObject):
174 rv = "%s:%s" % (unwrapped.__class__.__name__, unwrapped.id.val)
175 elif isinstance(object, RTimeI):
176 rv = time.ctime(unwrapped/1000.0)
177 elif isinstance(object, Details):
178 owner = None
179 group = None
180 if unwrapped.owner is not None:
181 owner = unwrapped.owner.id.val
182 if unwrapped.group is not None:
183 group = unwrapped.group.id.val
184 rv = "owner=%s;group=%s" % (owner, group)
185 else:
186 rv = unwrapped
187
188 cache[id(object)] = rv
189 return rv;
190
192 values = dict(values)
193 for x in ("_id", "_loaded"):
194 if x in values:
195 values.pop(x)
196 if "owner=None;group=None" == values.get("_details"):
197 values.pop("_details")
198 multi_valued = sorted([k for k in values if isinstance(values[k], list)])
199 false_valued = sorted([k for k in values if not values[k]])
200 for x in multi_valued + false_valued:
201 if x in values:
202 values.pop(x)
203
204 rv = dict()
205 for k, v in values.items():
206 if k.startswith("_"):
207 rv[k[1:]] = v
208 else:
209 rv[k] = v
210 return rv
211
212 - def project(self, querySvc, queryStr, params, ice_map):
213 import omero
214 try:
215 rv = querySvc.projection(queryStr, params, ice_map)
216 self.ctx.set("last.hql.rv", rv)
217 return rv
218 except omero.SecurityViolation, sv:
219 if "omero.group" in ice_map:
220 self.ctx.die(53, "SecurityViolation: Current user is not an admin and cannot use '--admin'")
221 else:
222 self.ctx.die(54, "SecurityViolation: %s" % sv)
223 except omero.QueryException, qe:
224 self.ctx.set("last.hql.rv", [])
225 self.ctx.die(52, "Bad query: %s" % qe.message)
226
227 try:
228 register("hql", HqlControl, HELP)
229 except NameError:
230 if __name__ == "__main__":
231 cli = CLI()
232 cli.register("hql", HqlControl, HELP)
233 cli.invoke(sys.argv[1:])
234