@@ -42,7 +42,7 @@ class which can be used to obtain `Driver` instances that are used for
4242STATEMENT_TYPE_SCHEMA_WRITE = "sw"
4343
4444
45- Latency = namedtuple ("Latency" , [ "overall" , "network" , "wait" ] )
45+ Latency = namedtuple ("Latency" , ( "overall" , "network" , "wait" ) )
4646
4747
4848class BenchTest (object ):
@@ -190,7 +190,8 @@ class ResultSummary(object):
190190 profile = None
191191
192192 #: Notifications provide extra information for a user executing a statement.
193- #: They can be warnings about problematic queries or other valuable information that can be presented in a client.
193+ #: They can be warnings about problematic queries or other valuable information that can be
194+ #: presented in a client.
194195 #: Unlike failures or errors, notifications do not affect the execution of a statement.
195196 notifications = None
196197
@@ -200,11 +201,17 @@ def __init__(self, statement, parameters, statement_type, statistics, plan, prof
200201 self .statement_type = statement_type
201202 self .statistics = StatementStatistics (statistics or {})
202203 if plan is not None :
203- self .plan = Plan (plan )
204+ self .plan = make_plan (plan )
204205 if profile is not None :
205- self .profile = ProfiledPlan (profile )
206+ self .profile = make_plan (profile )
206207 self .plan = self .profile
207- self .notifications = list (map (Notification , notifications ))
208+ self .notifications = []
209+ for notification in notifications :
210+ position = notification .get ("position" )
211+ if position is not None :
212+ position = Position (position ["offset" ], position ["line" ], position ["column" ])
213+ self .notifications .append (Notification (notification ["code" ], notification ["title" ],
214+ notification ["description" ], position ))
208215
209216
210217class StatementStatistics (object ):
@@ -256,79 +263,68 @@ def __repr__(self):
256263 return repr (vars (self ))
257264
258265
259- class Plan (object ):
260- """ This describes how the database will execute your statement.
266+ #: A plan describes how the database will execute your statement.
267+ #:
268+ #: operator_type:
269+ #: the name of the operation performed by the plan
270+ #: identifiers:
271+ #: the list of identifiers used by this plan
272+ #: arguments:
273+ #: a dictionary of arguments used in the specific operation performed by the plan
274+ #: children:
275+ #: a list of sub-plans
276+ Plan = namedtuple ("Plan" , ("operator_type" , "identifiers" , "arguments" , "children" ))
277+
278+
279+ #: A profiled plan describes how the database executed your statement.
280+ #:
281+ #: db_hits:
282+ #: the number of times this part of the plan touched the underlying data stores
283+ #: rows:
284+ #: the number of records this part of the plan produced
285+ ProfiledPlan = namedtuple ("ProfiledPlan" , Plan ._fields + ("db_hits" , "rows" ))
286+
287+ #: Representation for notifications found when executing a statement. A
288+ #: notification can be visualized in a client pinpointing problems or
289+ #: other information about the statement.
290+ #:
291+ #: code:
292+ #: a notification code for the discovered issue.
293+ #: title:
294+ #: a short summary of the notification
295+ #: description:
296+ #: a long description of the notification
297+ #: position:
298+ #: the position in the statement where this notification points to, if relevant.
299+ Notification = namedtuple ("Notification" , ("code" , "title" , "description" , "position" ))
300+
301+ #: A position within a statement, consisting of offset, line and column.
302+ #:
303+ #: offset:
304+ #: the character offset referred to by this position; offset numbers start at 0
305+ #: line:
306+ #: the line number referred to by the position; line numbers start at 1
307+ #: column:
308+ #: the column number referred to by the position; column numbers start at 1
309+ Position = namedtuple ("Position" , ("offset" , "line" , "column" ))
310+
311+
312+ def make_plan (plan_dict ):
313+ """ Construct a Plan or ProfiledPlan from a dictionary of metadata values.
314+
315+ :param plan_dict:
316+ :return:
261317 """
262-
263- #: The operation name performed by the plan
264- operator_type = None
265-
266- #: A list of identifiers used by this plan
267- identifiers = None
268-
269- #: A map of arguments used in the specific operation performed by the plan
270- arguments = None
271-
272- #: A list of sub plans
273- children = None
274-
275- def __init__ (self , plan ):
276- self .operator_type = plan ["operatorType" ]
277- self .identifiers = plan .get ("identifiers" , [])
278- self .arguments = plan .get ("args" , [])
279- self .children = [Plan (child ) for child in plan .get ("children" , [])]
280-
281-
282- class ProfiledPlan (Plan ):
283- """ This describes how the database excuted your statement.
284- """
285-
286- #: The number of times this part of the plan touched the underlying data stores
287- db_hits = 0
288-
289- #: The number of records this part of the plan produced
290- rows = 0
291-
292- def __init__ (self , profile ):
293- self .db_hits = profile .get ("dbHits" , 0 )
294- self .rows = profile .get ("rows" , 0 )
295- super (ProfiledPlan , self ).__init__ (profile )
296-
297-
298- class Notification (object ):
299- """ Representation for notifications found when executing a statement.
300- A notification can be visualized in a client pinpointing problems or other information about the statement.
301- """
302-
303- #: A notification code for the discovered issue.
304- code = None
305-
306- #: A short summary of the notification
307- title = None
308-
309- #: A long description of the notification
310- description = None
311-
312- #: The position in the statement where this notification points to, if relevant. This is a namedtuple
313- #: consisting of offset, line and column:
314- #:
315- #: - offset - the character offset referred to by this position; offset numbers start at 0
316- #:
317- #: - line - the line number referred to by the position; line numbers start at 1
318- #:
319- #: - column - the column number referred to by the position; column numbers start at 1
320- position = None
321-
322- def __init__ (self , notification ):
323- self .code = notification ["code" ]
324- self .title = notification ["title" ]
325- self .description = notification ["description" ]
326- position = notification .get ("position" )
327- if position is not None :
328- self .position = Position (position ["offset" ], position ["line" ], position ["column" ])
329-
330-
331- Position = namedtuple ('Position' , ['offset' , 'line' , 'column' ])
318+ operator_type = plan_dict ["operatorType" ]
319+ identifiers = plan_dict .get ("identifiers" , [])
320+ arguments = plan_dict .get ("args" , [])
321+ children = [make_plan (child ) for child in plan_dict .get ("children" , [])]
322+ if "dbHits" in plan_dict or "rows" in plan_dict :
323+ db_hits = plan_dict .get ("dbHits" , 0 )
324+ rows = plan_dict .get ("rows" , 0 )
325+ return ProfiledPlan (operator_type , identifiers , arguments , children , db_hits , rows )
326+ else :
327+ return Plan (operator_type , identifiers , arguments , children )
332328
333329
334330class Session (object ):
0 commit comments