RecordsetCursor class: Difference between revisions

From m204wiki
Jump to navigation Jump to search
mNo edit summary
mNo edit summary
 
(7 intermediate revisions by 2 users not shown)
Line 1: Line 1:
<!-- RecordsetCursor class -->
<!-- RecordsetCursor class -->
You can loop on the records in a Recordset or SortedRecordset object
You can loop on the records in a <var>[[Recordset class|Recordset]]</var> or <var>[[SortedRecordset class|SortedRecordset ]]</var> object
using the traditional User Language FOR EACH RECORD loop construct, as
using the traditional <var class="product">User Language</var> <var>For Each Record</var> loop construct, as
described in the preceding sections for those objects.
described in the preceding sections for those objects.
However, it can be
However, it can be convenient to advance through a record set and access its records
convenient to advance through a record set and access its records
outside the context of a single record loop.
outside the context of a single record loop.
   
   
The [[Janus SOAP]] RecordsetCursor object
The <var class="product">[[Janus SOAP]]</var> <var>RecordsetCursor</var> object
gives you this additional capability for both Recordset and
gives you this additional capability for both <var>Recordset</var> and <var>SortedRecordset</var> objects.
SortedRecordset objects.
Essentially, a <var>RecordsetCursor</var> is a position marker in a record set.
Essentially, a RecordsetCursor is a position
A cursor can be used to access the record at its position, or the cursor can be moved to a new position.
marker in a record set.
A cursor can be used to access the record at
its position, or the cursor can be moved to a new position.


==Cursor state==
==Cursor state==
A <var>RecordSetCursor</var> can be in various states as it navigates a record
A <var>RecordSetCursor</var> can be in various states as it navigates a record set:
set; these states are defined by the values of the <var>CursorState</var> [[Enumerations|enumeration]]:
<dl>
<dl>
<dt>BeforeStart
<dt>BeforeStart
Line 25: Line 20:
<dd>The cursor points to a record that is available for
<dd>The cursor points to a record that is available for
processing.
processing.
<dt>AfterEnd
<dt>AfterEnd
<dd>The cursor is positioned after the last record in
<dd>The cursor is positioned after the last record in
the set.
the set.
<dt>NoRecord
<dt>NoRecord
<dd>The cursor ''had'' a
<dd>The cursor ''had'' a
valid position identifying a record in a record set, but a subsequent operation
valid position identifying a record in a record set, but a subsequent operation
(A <var>Recordset</var> <var>[[Clear (Recordset subroutine)|Clear]]</var> or <var>[[RemoveRecord (Recordset subroutine)|RemoveRecord]]</var> method) removed the
(a <var>Recordset</var> <var>[[Clear (Recordset subroutine)|Clear]]</var> or <var>[[RemoveRecord (Recordset subroutine)|RemoveRecord]]</var> method) removed the
record from the underlying <var>Recordset</var>.
record from the underlying <var>Recordset</var>.
This state is new in <var class="product">Sirius Mods</var> version 7.0.
 
<dt>Empty
<dt>Empty
<dd>The cursor points to an empty record set.
<dd>The cursor points to an empty record set.
Line 39: Line 36:
</dl>
</dl>
   
   
The CursorState enumeration returns the state of a cursor:
These cursor states are the values returned by the <var>CursorState</var> [[Enumerations|enumeration]]:
<p class="code"> %state is enumeration CursorState
<p class="code">%state is enumeration CursorState
</p>
</p>
   
   
'''Note:''' As with all enumerations, the <var>ToString</var> method implicitly converts an enumeration value to a character string whose value is the name of the enumeration value. For more information about methods available to all enumerations, see [[Enumerations#Common enumeration methods|"Common enumeration methods"]].
'''Note:''' As with all enumerations, the <var>ToString</var> method implicitly converts an enumeration value to a character string whose value is the name of the enumeration value. For more information about methods available to all enumerations, see [[Enumerations#Common enumeration methods|Common enumeration methods]].
   
   
The <var>RecordsetCursor</var> read-only property <var>[[State (RecordsetCursor function)|State]]</var> returns a <var>CursorState</var> enumeration that indicates the current state of the cursor.
The <var>RecordsetCursor</var> read-only property <var>[[State (RecordsetCursor function)|State]]</var> returns a <var>CursorState</var> enumeration that indicates the current state of the cursor.
Line 52: Line 49:


==Declaration and instantiation==
==Declaration and instantiation==
A RecordsetCursor is declared like any other file or group context
A <var>RecordsetCursor</var> is declared like any other file or group context
based object.
based object.
For example:
For example:
<p class="code"> %myCurs1 is object RecordsetCursor in file ftptest
<p class="code">%myCurs1 is object RecordsetCursor in file ftptest
   
   
%myCurs2 is object RecordsetCursor in group foo
%myCurs2 is object RecordsetCursor in group foo
</p>
</p>
   
   
Prior to version 7.6 of the <var class="product">Sirius Mods</var>, the RecordsetCursor class
Prior to version 7.6 of the <var class="product">Sirius Mods</var>, the <var>RecordsetCursor</var> class
contained no native constructor methods, and
contained no native constructor methods, and
the way to instantiate a RecordsetCursor object is to use
the way to instantiate a <var>RecordsetCursor</var> object is to use
the Cursor method provided by
the <var>Cursor</var> method provided by both the <var>Recordset</var> and <var>SortedRecordset</var> classes.
both the Recordset and SortedRecordset classes.
In version 7.6, the <var>RecordsetCursor</var> <var>New</var> method was added,
In version 7.6, the RecordsetCursor New method was added,
primarily to enable the creation of extension classes of the <var>RecordsetCursor</var> class, which the <var>Cursor</var> constructor
primarily to enable the creation of extension classes of
the RecordsetCursor class, which the Cursor constructor
cannot do.
cannot do.
   
   
Instantiation by the Cursor and New methods is described below.
Instantiation by the <var>Cursor</var> and <var>New</var> methods is described below.
<ul>
<ul>
<li>The Cursor method instantiates a RecordsetCursor for a
<li>The <var>Cursor</var> method instantiates a <var>RecordsetCursor</var> for a
particular instance of a Recordset or SortedRecordset object.
particular instance of a <var>Recordset</var> or <var>SortedRecordset</var> object.
The method takes no arguments.
The method takes no arguments.
If the set has at least
If the set has at least one record, <var>Cursor</var> instantiates an instance of the <var>RecordsetCursor</var> object.
one record, Cursor instantiates an instance of the RecordsetCursor object.
If <var>Cursor</var> is called on a set that "isEmpty" (0 records), it
If Cursor is called on a set that &ldquo;isEmpty&rdquo; (0 records), it
returns a <var>Null</var> object.
returns a Null object.
   
   
Here is a small syntax example:
Here is a small syntax example:
<p class="code"> %rs is object recordSet in file stooges
<p class="code">%rs is object recordSet in file stooges
%srs is object SortedRecordset in file stooges
%srs is object SortedRecordset in file stooges
%myCursor1 is object RecordsetCursor in file stooges
%myCursor1 is object RecordsetCursor in file stooges
%myCursor2 is object RecordsetCursor in file stooges
%myCursor2 is object RecordsetCursor in file stooges
  ...
...
fd to %rs
fd to %rs
    end find
  end find
  ...
...
sort records in %rs to %srs by name
sort records in %rs to %srs by name
  ...
...
%myCursor1 = %rs:Cursor
%myCursor1 = %rs:Cursor
%myCursor2 = %srs:Cursor
%myCursor2 = %srs:Cursor
</p>
</p>
<li>Since a RecordsetCursor references a Recordset or SortedRecordset object
 
and may have a LoopLockStrength, the RecordsetCursor <code>New</code>
<li>Since a <var>RecordsetCursor</var> references a <var>Recordset</var> or <var>SortedRecordset</var> object
and may have a <var>LoopLockStrength</var>, the <var>RecordsetCursor</var> <var>[[New (RecordsetCursor constructor)|New]]</var>
constructor is of this form:
constructor is of this form:
==Unknown title==
 
<p class="pre"> %(RecordsetCursor):New(<recset> [,loopLockStrength=<lls>])
<p class="syntax">%(<span class="literal">RecordsetCursor</span>):<span class="literal">New</span>(<span class="term">recset</span> <span class="squareb">[</span>, <span class="literal">LoopLockStrength</span>=<span class="term">lls</span><span class="squareb">]</span>)
</p>
</p>
   
   
Where:
Where:
<dl>
<dl>
<dt><recset>
<dt><i>recset</i>
<dd>A required Recordset or SortedRecordset object.
<dd>A required <var>Recordset</var> or <var>SortedRecordset</var> object.
<dt><lls>
 
<dd>A LockStrength enumeration setting the minimum lock strength for a record
<dt><i>lls</i>
in a For Record At loop on a RecordsetCursor object.
<dd>A <var>LockStrength</var> enumeration setting the minimum lock strength for a record
This argument is only valid if <code><recset></code> is a
in a <var>For Record At</var> loop on a <var>RecordsetCursor</var> object.
SortedRecordset object.
This argument is only valid if <var class="term">recset</var> is a <var>SortedRecordset</var> object.
</dl>
</dl>
'''Note:'''
'''Note:'''
If <code><recset></code> is empty, New returns a RecordsetCursor
If <var class="term">recset</var> is empty, <var>New</var> returns a <var>RecordsetCursor</var>
object with the state <code>Empty</code>.
object with the state <var>Empty</var>.
This is different from the Cursor methods instantiation,
This is different from the <var>Cursor</var> methods instantiation,
which return a null if <code><recset></code> is empty.
which return a null if <var class="term">recset</var> is empty.
</ul>
</ul>
   
   
With either of the instantiation methods,
With either of the instantiation methods,
when a RecordsetCursor is instantiated, it is automatically
when a <var>RecordsetCursor</var> is instantiated, it is automatically
positioned on the first record in the set (state=HasRecord).
positioned on the first record in the set (<code>state=HasRecord</code>).
   
   
You can have as many cursors as you want for a record set.
You can have as many cursors as you want for a record set.
==Referencing a RecordsetCursor object==
==Referencing a RecordsetCursor object==
If the [[State (RecordsetCursor property)|state]] of a RecordsetCursor is HasRecord, it can be
If the [[State (RecordsetCursor function)|state]] of a <var>RecordsetCursor</var> is <var>HasRecord</var>, it can be
referenced on a new FOR/END FOR variation:
referenced on a new <var>For</var>/<var>End For</var> variation:
<p class="code"> FOR RECORD AT CURSOR %RecordsetCursorObject
<p class="code">For Record At Cursor %RecordsetCursorObject
    ... whatever
  ... whatever
END FOR
End For
</p>
</p>
   
   
If the cursor is not in HasRecord state, the request is cancelled.
If the cursor is not in <var>HasRecord</var> state, the request is cancelled.
   
   
Processing a record with this construct is very much like processing
Processing a record with this construct is very much like processing
it with a FOR EACH RECORD loop that runs on a set that only contains
it with a <var>For Each Record</var> loop that runs on a set that only contains that record.
that record.
This means:
This means:
<ul>
<ul>
<li>No extra record locking is done.
<li>No extra record locking is done.
The record is locked (or not) at
The record is locked (or not) at whatever level the underlying record set is.
whatever level the underlying record set is.
 
<li>If the cursor is for a SortedRecordset that was created using a
<li>If the cursor is for a <var>SortedRecordset</var> that was created using a
SORT RECORDS TO statement, the records returned will be copies
<var>Sort Records To</var> statement, the records returned will be copies of the actual records.
of the actual records.
If the <var>SortedRecordset</var> was created with
If the SortedRecordset was created with
<var>Sort Record Keys</var>, the actual Table B record from the file is returned.
SORT RECORD KEYS, the actual Table B record from the file is
This is consistent with the contrasting behavior of <var>Sort Records</var> and
returned.
<var>Sort Record Keys</var> elsewhere in <var class="product">Model 204</var>.
This is consistent with the contrasting behaviour of SORT RECORDS and
SORT RECORD KEYS elsewhere in <var class="product">Model 204</var>.
</ul>
</ul>
   
   
The <code>FOR RECORD %recobj</code> construct can be used on the
The <code>For Record %recobj</code> construct can be used on the
result of the
result of the <var>RecordsetCursor</var> <var>[[CurrentRecord (RecordsetCursor function)|CurrentRecord]]</var> method (or on a <var>Record</var> object
RecordsetCursor CurrentRecord method (or on a record object
to which the method result was assigned).
to which the method result was assigned).
For example:
For example:
<p class="code"> FOR RECORD %myCursor1:CurrentRecord
<p class="code">For Record %myCursor1:CurrentRecord
    ... whatever
  ... whatever
END FOR
End For
</p>
</p>
   
   
Or, for example:
Or, for example:
<p class="code"> %r is object record in foo
<p class="code">%r is object record in foo
%r = %myCursor1:CurrentRecord(exclusive)
%r = %myCursor1:CurrentRecord(exclusive)
FOR RECORD %r
For Record %r
    ... whatever
  ... whatever
END FOR
End For
</p>
</p>
This second technique is less efficient, because you incur the
This second technique is less efficient, because you incur the
overhead of record Object instantiation and record locking.
overhead of <var>Record</var> object instantiation and record locking.
It is more
It is more flexible because you can control the locking strength.
flexible because you can control the locking strength.
   
   
In addition, with this technique you always refer to the real record in Table
In addition, with this technique you always refer to the real record in Table
B, and never to a Sort copy.
B, and never to a <var>Sort</var> copy.
 
===LoopLockStrength for RecordsetCursors===
===LoopLockStrength for RecordsetCursors===
In addition to the LockStrength property, in <var class="product">Sirius Mods</var> 7.0 and later,
In addition to the <var>[[LockStrength (RecordsetCursor function)|LockStrength]]</var> property, in <var class="product">Sirius Mods</var> 7.0 and later,
all RecordsetCursor objects also have a LoopLockStrength property.
all <var>RecordsetCursor</var> objects also have a <var>[[LoopLockStrength (RecordsetCursor property)|LoopLockStrength]]</var> property.
Like the LockStrength property, the LoopLockStrength property's values
Like the <var>LockStrength</var> property, the <var>LoopLockStrength</var> property's values
are of the LockStrength enumeration.
are of the <var>LockStrength</var> enumeration.
The LoopLockStrength property indicates the minimum lock strength for
The <var>LoopLockStrength</var> property indicates the minimum lock strength for
the record being processed in an iteration of a For Record At loop
the record being processed in an iteration of a <var>For Record At</var> loop
on a RecordsetCursor object.
on a <var>RecordsetCursor</var> object.
   
   
If the LoopLockStrength is the same as or weaker than the LockStrength
If the <var>LoopLockStrength</var> is the same as or weaker than the <var>LockStrength</var>
of a RecordsetCursor object (which is, in fact, the lock strength of
of a <var>RecordsetCursor</var> object (which is, in fact, the lock strength of the underlying <var>Recordset</var> object),
the underlying Recordset object),
no action is required at the start of each loop
no action is required at the start of each loop
&mdash; the record in the iteration is known to be locked at the
&mdash; the record in the iteration is known to be locked at the
strength of the Recordset which is greater than the LoopLockStrength.
strength of the <var>Recordset</var> which is greater than the <var>LoopLockStrength</var>.
If, however, the LoopLockStrength is stronger than the LockStrength,
If, however, the <var>LoopLockStrength</var> is stronger than the <var>LockStrength</var>,
each execution of a For Record At loop on a RecordsetCursor object tries
each execution of a <var>For Record At</var> loop on a <var>RecordsetCursor</var> object tries
to obtain a LoopLockStrength level lock on the record in the iteration.
to obtain a <var>LoopLockStrength</var> level lock on the record in the iteration.
If successful, the iteration is processed and the lock is released
If successful, the iteration is processed and the lock is released at the end of the loop execution.
at the end of the loop execution.
   
   
The default value of LoopLockStrength is <code>None</code>, which means that
The default value of <var>LoopLockStrength</var> is <var>None</var>, which means that
no additional locking is performed for the record in the RecordsetCursor
no additional locking is performed for the record in the <var>RecordsetCursor</var>
during loop processing.
during loop processing.
   
   
LoopLockStrength locking behavior is identical to the locking
<var>LoopLockStrength</var> locking behavior is identical to the locking
behavior of the For Record Number (FRN) statement.
behavior of the <var>For Record Number</var> (<var>FRN</var>) statement.
The meanings of certain statements in an On Record Locking conflict
The meanings of certain statements in an <var>On Record Locking</var> conflict
unit are identical to their meaning for a For Record Number statement
unit are identical to their meaning for a <var>For Record Number</var> statement conflict:
conflict:
<dl>
<dl>
<dt>Bypass
<dt>Bypass
<dd>Causes processing of the record to be skipped, which means that
<dd>Causes processing of the record to be skipped, which means that
the For Record loop is not processed.
the <var>For Record</var> loop is not processed.
<dt>Retry
<dt>Retry
<dd>Causes the For Record At statement to be re-executed and
<dd>Causes the <var>For Record At</var> statement to be re-executed and
to try again to lock the record at the LoopLockStrength level.
to try again to lock the record at the <var>LoopLockStrength</var> level.
</dl>
</dl>
   
   
There are many similarities in LoopLockStrength processing for
There are many similarities in <var>LoopLockStrength</var> processing for
RecordsetCursor and <var>Recordset</var> objects.
<var>RecordsetCursor</var> and <var>Recordset</var> objects.
For more information about the use of LoopLockStrength with Recordset
For more information about the use of <var>LoopLockStrength</var> with <var>Recordset</var>
objects see [[Recordset class#LoopLockStrength for Recordsets|"LoopLockStrength for Recordsets"]].
objects see [[Recordset class#LoopLockStrength for Recordsets|LoopLockStrength for Recordsets]].
 
==Discarding a cursor==
==Discarding a cursor==
In addition to the standard discard (<code>%myCursor1:Discard</code>),
In addition to the standard discard (<code>%myCursor1:Discard</code>),
you can also use the Close method to discard a RecordsetCursor object:
you can also use the <var>[[Close (RecordsetCursor subroutine)|Close]]</var> method to discard a <var>RecordsetCursor</var> object:
<p class="code"> %myCursor1:close
<p class="code">%myCursor1:close
</p>
</p>


==List of RecordsetCursor methods==
==List of RecordsetCursor methods==
The [[List of RecordsetCursor methods|"List of RecordsetCursor methods"]] shows all the class methods.
The [[List of RecordsetCursor methods]] shows all the class methods.


[[Category:System classes]]
[[Category:System classes]]

Latest revision as of 21:18, 25 August 2014

You can loop on the records in a Recordset or SortedRecordset object using the traditional User Language For Each Record loop construct, as described in the preceding sections for those objects. However, it can be convenient to advance through a record set and access its records outside the context of a single record loop.

The Janus SOAP RecordsetCursor object gives you this additional capability for both Recordset and SortedRecordset objects. Essentially, a RecordsetCursor is a position marker in a record set. A cursor can be used to access the record at its position, or the cursor can be moved to a new position.

Cursor state

A RecordSetCursor can be in various states as it navigates a record set:

BeforeStart
The cursor is positioned before the first record in the set.
HasRecord
The cursor points to a record that is available for processing.
AfterEnd
The cursor is positioned after the last record in the set.
NoRecord
The cursor had a valid position identifying a record in a record set, but a subsequent operation (a Recordset Clear or RemoveRecord method) removed the record from the underlying Recordset.
Empty
The cursor points to an empty record set. This state is new in Sirius Mods version 7.6.

These cursor states are the values returned by the CursorState enumeration:

%state is enumeration CursorState

Note: As with all enumerations, the ToString method implicitly converts an enumeration value to a character string whose value is the name of the enumeration value. For more information about methods available to all enumerations, see Common enumeration methods.

The RecordsetCursor read-only property State returns a CursorState enumeration that indicates the current state of the cursor.

Any method that repositions the cursor returns a CursorState enumeration that indicates the new state of the cursor after the completion of the operation performed by the method.

Declaration and instantiation

A RecordsetCursor is declared like any other file or group context based object. For example:

%myCurs1 is object RecordsetCursor in file ftptest %myCurs2 is object RecordsetCursor in group foo

Prior to version 7.6 of the Sirius Mods, the RecordsetCursor class contained no native constructor methods, and the way to instantiate a RecordsetCursor object is to use the Cursor method provided by both the Recordset and SortedRecordset classes. In version 7.6, the RecordsetCursor New method was added, primarily to enable the creation of extension classes of the RecordsetCursor class, which the Cursor constructor cannot do.

Instantiation by the Cursor and New methods is described below.

  • The Cursor method instantiates a RecordsetCursor for a particular instance of a Recordset or SortedRecordset object. The method takes no arguments. If the set has at least one record, Cursor instantiates an instance of the RecordsetCursor object. If Cursor is called on a set that "isEmpty" (0 records), it returns a Null object. Here is a small syntax example:

    %rs is object recordSet in file stooges %srs is object SortedRecordset in file stooges %myCursor1 is object RecordsetCursor in file stooges %myCursor2 is object RecordsetCursor in file stooges ... fd to %rs end find ... sort records in %rs to %srs by name ... %myCursor1 = %rs:Cursor %myCursor2 = %srs:Cursor

  • Since a RecordsetCursor references a Recordset or SortedRecordset object and may have a LoopLockStrength, the RecordsetCursor New constructor is of this form:

    %(RecordsetCursor):New(recset [, LoopLockStrength=lls])

    Where:

    recset
    A required Recordset or SortedRecordset object.
    lls
    A LockStrength enumeration setting the minimum lock strength for a record in a For Record At loop on a RecordsetCursor object. This argument is only valid if recset is a SortedRecordset object.

    Note: If recset is empty, New returns a RecordsetCursor object with the state Empty. This is different from the Cursor methods instantiation, which return a null if recset is empty.

With either of the instantiation methods, when a RecordsetCursor is instantiated, it is automatically positioned on the first record in the set (state=HasRecord).

You can have as many cursors as you want for a record set.

Referencing a RecordsetCursor object

If the state of a RecordsetCursor is HasRecord, it can be referenced on a new For/End For variation:

For Record At Cursor %RecordsetCursorObject ... whatever End For

If the cursor is not in HasRecord state, the request is cancelled.

Processing a record with this construct is very much like processing it with a For Each Record loop that runs on a set that only contains that record. This means:

  • No extra record locking is done. The record is locked (or not) at whatever level the underlying record set is.
  • If the cursor is for a SortedRecordset that was created using a Sort Records To statement, the records returned will be copies of the actual records. If the SortedRecordset was created with Sort Record Keys, the actual Table B record from the file is returned. This is consistent with the contrasting behavior of Sort Records and Sort Record Keys elsewhere in Model 204.

The For Record %recobj construct can be used on the result of the RecordsetCursor CurrentRecord method (or on a Record object to which the method result was assigned). For example:

For Record %myCursor1:CurrentRecord ... whatever End For

Or, for example:

%r is object record in foo %r = %myCursor1:CurrentRecord(exclusive) For Record %r ... whatever End For

This second technique is less efficient, because you incur the overhead of Record object instantiation and record locking. It is more flexible because you can control the locking strength.

In addition, with this technique you always refer to the real record in Table B, and never to a Sort copy.

LoopLockStrength for RecordsetCursors

In addition to the LockStrength property, in Sirius Mods 7.0 and later, all RecordsetCursor objects also have a LoopLockStrength property. Like the LockStrength property, the LoopLockStrength property's values are of the LockStrength enumeration. The LoopLockStrength property indicates the minimum lock strength for the record being processed in an iteration of a For Record At loop on a RecordsetCursor object.

If the LoopLockStrength is the same as or weaker than the LockStrength of a RecordsetCursor object (which is, in fact, the lock strength of the underlying Recordset object), no action is required at the start of each loop — the record in the iteration is known to be locked at the strength of the Recordset which is greater than the LoopLockStrength. If, however, the LoopLockStrength is stronger than the LockStrength, each execution of a For Record At loop on a RecordsetCursor object tries to obtain a LoopLockStrength level lock on the record in the iteration. If successful, the iteration is processed and the lock is released at the end of the loop execution.

The default value of LoopLockStrength is None, which means that no additional locking is performed for the record in the RecordsetCursor during loop processing.

LoopLockStrength locking behavior is identical to the locking behavior of the For Record Number (FRN) statement. The meanings of certain statements in an On Record Locking conflict unit are identical to their meaning for a For Record Number statement conflict:

Bypass
Causes processing of the record to be skipped, which means that the For Record loop is not processed.
Retry
Causes the For Record At statement to be re-executed and to try again to lock the record at the LoopLockStrength level.

There are many similarities in LoopLockStrength processing for RecordsetCursor and Recordset objects. For more information about the use of LoopLockStrength with Recordset objects see LoopLockStrength for Recordsets.

Discarding a cursor

In addition to the standard discard (%myCursor1:Discard), you can also use the Close method to discard a RecordsetCursor object:

%myCursor1:close

List of RecordsetCursor methods

The List of RecordsetCursor methods shows all the class methods.