Is it possible to extend NIL?

I was trying to write a shortcut for a frequently use check to see if a recordset has any records.

Here is what I tried:

'this works
if rs <> nil and rs.recordcount > 0 then 'do stuff...

'none of these methods work when rs is nil
if rs.HasRecords then 'do stuff...

Function HasRecords(extends rs as RecordSet) As Boolean
  if rs = nil then return false
  if rs.RecordCount > 0 Then Return True else return False
End Function

'this method is invalid
Function HasRecords(extends rs as nil) As Boolean
  return false
End Function

I know I could catch the exception with a try statement but that wouldn’t be a shortcut.

It is possible to do it with a regular method, but my question is can I do this as an extend?

'this works
if HasRecords(rs) then 'do stuff...

Function HasRecords(rs as RecordSet) As Boolean
  if rs <> nil and rs.RecordCount > 0 Then Return True else return False
End Function

see <https://xojo.com/issue/31205>

Just throwing this out there; it probably will feel funky but…

Create your own subclass of RecordSet that auto-converts from a RecordSet (which gets instantiated even if the received object is nil)

[code]Class MyRS Inherits RecordSet

Public Property mInstance as RecordSet

Public Sub Operator_Convert(rs As RecordSet)
mInstance = rs
End Sub

Public Function HasRecords() as Boolean
return mInstance <> nil and mInstance.RecordCount > 0
End Function

End Class[/code]

[code]dim rs As RecordSet

dim c As MyRS = rs

MsgBox Str(c.HasRecords)[/code]

It’ll feel funky because you don’t instantiate/new the MyRS, just assign to it and thereafter assume it’s not nil. Yeah, I know, must be breaking a lot of standard practices.

Edit: Actually it’ll be a lot my work than I thought. I was thinking, it being a subclass you could then still pass MyRS to all the places you use a RecordSet. But all the RecordSet methods would need to be overridden and call though to mInstance. And properties couldn’t be overridden. OK, forget this idea :stuck_out_tongue:

No.

That is exactly what I wanted. Non-essential, but would be useful functionality.

In this case you only get NIL if the SQL SELECT statement for getting the recordset is incorrect. If The Select statement is legal and there are no records selected, you get a recordset where recordcount = 0 and EOF is True.

IMO, given that you very rarely, if ever, treat a NIL recordSet as a Recordset with 0 records… A NIL RecordSet will almost always mean you have a bug in your code that needs to be fixed.

  • karen

Hmmm… I see. I started out that way back when I was inexperienced.
I suppose adding the nil check allows my code to continue (or rather correctly skip stuff that would cause further errors) after a db error occurs.

Would it be possible for rs to be nil without a db.error occurring?

For easy debugging I check for errors after every db call:

dim rs as recordset = db.sqlselect("SELECT * FROM SomeTable")
db.errcheck "ThisMethod_Or_Event 1"
if rs <> nil and rs.recordcount 0 then 'do stuff...


Sub ErrCheck(Extends DB as SQLiteDatabase, msg as String = "", Log as Boolean = True)
  if db.Error then
    dim em As String = "Error: " + db.ErrorMessage + EndOfLine + msg
    if Log Then
      pSQLps = Main.MainDb.Prepare("INSERT INTO ErrorLog(Value,UserName,Time) VALUES($1,$2,'now()')")
      pSQLps.SQLExecute(em,System.EnvironmentVariable("COMPUTERNAME"))
    end if
    msgbox em
  end if
End Sub

Only if you never did the sqlselect. I always code defensively and check for nil, but only for the case where the method is called incorrectly (a bug in my code). If you call sqlselect, the recordset will only be nil if there is a db.error.

So I’m on the right track. Check for db.error, log /handle error. Check for rs nil to prevent further errors in the event of an error.
I’m a little paranoid about err handling. I probably have error handling in places where it’s impossible for an error to occur.

I’ve noticed code like this sometimes:

if listbox1.listindex = -1 then return
'...

if listbox1.listindex > -1 then listbox1(listbox1.listindex,0) = 'test'

FYI: >95% of the use of error check is to assist debugging.

My favorite support pet peeve: ‘It doesn’t work at all anymore.’ or ‘It’s not letting me do anything.’

Me: ‘Were there any error messages?’
Reply: ‘I think there was one or two.’

I just proved myself wrong. Can’t be too careful! Probably an update timer changed the listindex.

The modal window pauses your code long enough for the listbox to be modified. Without it, there wouldn’t be a problem.

just store the index in a local variable, so a change of selection doesn’t hurt you.