How do I generalize a class?

I use a sqlite database for my app called ModelParamDB. The program uses ModelParamDB for a lot of useful stuff.

So it is defined as a sqlite database: class ModelParamDB as SQLiteDatabase

My app also talks to an ODBC database where it operates on data there. In a multiuser situation where several people on a team may be using a version of my app, I need to define ModelParamDB as an ODBC database. ModelParamDB keeps track of information that should be shared among the team.

In order to avoid a lot of if remote then … else local code in my app, how can I alias the ModelParamDB as either an ODBC database or a sqlite database.

So something like Class ModelParamDB with two types: SQLite database, and ODBC database.

I know it can be done, but just don’t know how to define it.

What you would want to do is create a class interface. A class interface is basically a new type that you create that has specific methods associated with it. So you may have database write methods define or search methods, etc. When you create the class, you create just the method names. Then when you implement the interface in your class, those methods get added. There in those methods you put the bits of code that are specific and required for that particular class (SQLIte commands goes in the SQLite class and ODBC commands in the ODBC class).

In your code, you can simply refer to the interface name you created. So if you create an interface called MyDBinterface, you can do things like:

MyDBInterface.Query or MyDBInterface.Write if Query and Write are methods defined in the interface. This way you really don’t care what class is being used as they are both the same new type. This is how you make things generic.

I do this in my code with TCPSockets and Serial connections. The user selects which one they want to use and off we go. My interface is called IODevice. I have an object of type IODevice defined in my classes. Once I define what IODevice is when the user chooses it, all the rest of my code then doesn’t care if the IODevice is an TCPSocket or a Serial connection. It’s an “IODevice.”

It takes a while to get your head around the concept of class interfaces and I still struggle with it some times. But this is truly how you can make things totally generic.

Jon

OK, so I create class named myDatabases or something which contain on ODBC object and a SQLite object. Then at startup, the user selects the database he wants to use, which is a switch in the class, like myDatabase.location (local or remote) as string, myDatabase.Query as string, myDatabase.recordset to deliver the results. When i instantiate the object, based on what the user has selected, I open an ODBC object or a SQLite object.

This user sets the database type at startup, the class instantiates the correct database object, and calls the appropriate query. He then returns the record set.

Is this the idea?

[quote=135569:@Kenneth Reed]OK, so I create class named myDatabases or something which contain on ODBC object and a SQLite object.
[/quote]

Not exactly. You create two classes - One that is set up to handle all of the SQLite work that needs to be done and one that handles all the ODBC work that needs to be done. You create a class interface with a set of methods that will basically be your way “in” to those classes from outside. You then add that interface to each class.

[quote]
Then at startup, the user selects the database he wants to use, which is a switch in the class, like myDatabase.location (local or remote) as string, myDatabase.Query as string, myDatabase.recordset to deliver the results. When i instantiate the object, based on what the user has selected, I open an ODBC object or a SQLite object.

This user sets the database type at startup, the class instantiates the correct database object, and calls the appropriate query. He then returns the record set.

Is this the idea?[/quote]

Again close. The user does select what database type they want to use. Here - let me try to show you with an example…

https://www.dropbox.com/s/u532nu8htialdi8/ClassInterfaceDBExample.xojo_binary_project?dl=0

Here I created two classes - a SQLite Class and an ODBC class. Each contain a respective database object and methods. They are also members of a class interface called DatabaseInterfaceClass. That class has some methods like “Query” assigned to it.

You pick which database you want from the pop-up and then assign the resulting database to the property of the window called DBClass that is of type DatabaseInterfaceClass. You’ll see it all in there. Now when you want to run any of the associated methods, you just call DBClass.Commit or DBClass.Query (actually query is a function that returns a record set). Look at the code in the pushbutton action event.

This example won’t run meaningfully as it’s missing all the database files, etc. but you should be able to see the idea behind the class interface from this. Let me know if you get it.

Got it, thanks 10**9

[quote=135569:@Kenneth Reed]OK, so I create class named myDatabases or something which contain on ODBC object and a SQLite object. Then at startup, the user selects the database he wants to use, which is a switch in the class, like myDatabase.location (local or remote) as string, myDatabase.Query as string, myDatabase.recordset to deliver the results. When i instantiate the object, based on what the user has selected, I open an ODBC object or a SQLite object.

This user sets the database type at startup, the class instantiates the correct database object, and calls the appropriate query. He then returns the record set.

Is this the idea?[/quote]
Since the database classes are so similar, this is the approach I take. The advantage is that all the code for each particular function is in the same place, so you can see the variations all at once. If I were dealing with dissimilar classes, such as TCPSocket and Serial, then I would definitely use a class interface. But not for similar classes like databases.

I suppose that is true. I am really not sure how much different the two database formats are. But I would not call your solution generalizing a class which was the original question. :slight_smile: