@@ -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 ):
@@ -138,10 +138,7 @@ def on_footer(self, metadata):
138138 """ Called on receipt of the result footer.
139139 """
140140 self .complete = True
141- self .summary = ResultSummary (self .statement , self .parameters ,
142- metadata .get ("type" ), metadata .get ("stats" ),
143- metadata .get ("plan" ), metadata .get ("profile" ),
144- metadata .get ("notifications" , []))
141+ self .summary = ResultSummary (self .statement , self .parameters , ** metadata )
145142 if self .bench_test :
146143 self .bench_test .end_recv = perf_counter ()
147144
@@ -190,21 +187,28 @@ class ResultSummary(object):
190187 profile = None
191188
192189 #: 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.
190+ #: They can be warnings about problematic queries or other valuable information that can be
191+ #: presented in a client.
194192 #: Unlike failures or errors, notifications do not affect the execution of a statement.
195193 notifications = None
196194
197- def __init__ (self , statement , parameters , statement_type , statistics , plan , profile , notifications ):
195+ def __init__ (self , statement , parameters , ** metadata ):
198196 self .statement = statement
199197 self .parameters = parameters
200- self .statement_type = statement_type
201- self .statistics = StatementStatistics (statistics or {} )
202- if plan is not None :
203- self .plan = Plan ( plan )
204- if profile is not None :
205- self .profile = ProfiledPlan ( profile )
198+ self .statement_type = metadata . get ( "type" )
199+ self .statistics = StatementStatistics (metadata . get ( "stats" , {}) )
200+ if " plan" in metadata :
201+ self .plan = make_plan ( metadata [ " plan" ] )
202+ if " profile" in metadata :
203+ self .profile = make_plan ( metadata [ " profile" ] )
206204 self .plan = self .profile
207- self .notifications = list (map (Notification , notifications ))
205+ self .notifications = []
206+ for notification in metadata .get ("notifications" , []):
207+ position = notification .get ("position" )
208+ if position is not None :
209+ position = Position (position ["offset" ], position ["line" ], position ["column" ])
210+ self .notifications .append (Notification (notification ["code" ], notification ["title" ],
211+ notification ["description" ], position ))
208212
209213
210214class StatementStatistics (object ):
@@ -256,79 +260,68 @@ def __repr__(self):
256260 return repr (vars (self ))
257261
258262
259- class Plan (object ):
260- """ This describes how the database will execute your statement.
263+ #: A plan describes how the database will execute your statement.
264+ #:
265+ #: operator_type:
266+ #: the name of the operation performed by the plan
267+ #: identifiers:
268+ #: the list of identifiers used by this plan
269+ #: arguments:
270+ #: a dictionary of arguments used in the specific operation performed by the plan
271+ #: children:
272+ #: a list of sub-plans
273+ Plan = namedtuple ("Plan" , ("operator_type" , "identifiers" , "arguments" , "children" ))
274+
275+
276+ #: A profiled plan describes how the database executed your statement.
277+ #:
278+ #: db_hits:
279+ #: the number of times this part of the plan touched the underlying data stores
280+ #: rows:
281+ #: the number of records this part of the plan produced
282+ ProfiledPlan = namedtuple ("ProfiledPlan" , Plan ._fields + ("db_hits" , "rows" ))
283+
284+ #: Representation for notifications found when executing a statement. A
285+ #: notification can be visualized in a client pinpointing problems or
286+ #: other information about the statement.
287+ #:
288+ #: code:
289+ #: a notification code for the discovered issue.
290+ #: title:
291+ #: a short summary of the notification
292+ #: description:
293+ #: a long description of the notification
294+ #: position:
295+ #: the position in the statement where this notification points to, if relevant.
296+ Notification = namedtuple ("Notification" , ("code" , "title" , "description" , "position" ))
297+
298+ #: A position within a statement, consisting of offset, line and column.
299+ #:
300+ #: offset:
301+ #: the character offset referred to by this position; offset numbers start at 0
302+ #: line:
303+ #: the line number referred to by the position; line numbers start at 1
304+ #: column:
305+ #: the column number referred to by the position; column numbers start at 1
306+ Position = namedtuple ("Position" , ("offset" , "line" , "column" ))
307+
308+
309+ def make_plan (plan_dict ):
310+ """ Construct a Plan or ProfiledPlan from a dictionary of metadata values.
311+
312+ :param plan_dict:
313+ :return:
261314 """
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' ])
315+ operator_type = plan_dict ["operatorType" ]
316+ identifiers = plan_dict .get ("identifiers" , [])
317+ arguments = plan_dict .get ("args" , [])
318+ children = [make_plan (child ) for child in plan_dict .get ("children" , [])]
319+ if "dbHits" in plan_dict or "rows" in plan_dict :
320+ db_hits = plan_dict .get ("dbHits" , 0 )
321+ rows = plan_dict .get ("rows" , 0 )
322+ return ProfiledPlan (operator_type , identifiers , arguments , children , db_hits , rows )
323+ else :
324+ return Plan (operator_type , identifiers , arguments , children )
332325
333326
334327class Session (object ):
0 commit comments