electronic.alchemy :: Using Fins.Model in standalone applications
electronic.alchemy
where the past meets the future
pike > Fins > Developer > StandaloneModel

Using Fins.Model in standalone applications

Created by hww3. Last updated by hww3, 10 years ago. Version #5.

While the Fins Model was originally designed to be used within a Fins based web application, it can also be easily used in a standalone mode. In this example, we demonstrate the use of the Fins.Model framework in a simple command line script.

Note that you don't ever need to create a full Fins app to use this technique, but creating a Fins app allows us to use the model builder tool (pike -x fins model). The model builder tool makes it easier to get started quickly by creating the data mapping and object instance definitions for any database tables we want to map. Once you have at least one Data Mapping and one Object Instance class created, it's easy use them as templates to create others later, so you can easily discard the Fins app you create after moving the Data Model definition class into your own app. We'll demonstrate this technique below.

Also, note that there is a certain amount of startup overhead if you're using the fully automatic model configuration mechanism. Otherwise, though, using Fins.Model should be quick and easy.

Quick directions for using the model in standalone mode:

  1. run pike -Mlib -x fins create MTA (for "my test application")
  2. edit MTA/config/dev.cfg, to define the sql url
  3. create tables in database
  4. run pike -Mlib -x fins model MTA scan, which will create stub classes in MTA/modules/MTA.pmod
  5. copy MTA/modules/MTA.pmod someplace more convenient for your app, preferably in your module path
  6. modify the example below as needed (ie, change the database connect string and name of the module that contains your model stub classes), then run and enjoy!
Note that you really only need to perform steps 3 and 6, as well as create any necessary classes in your mymodel.Objects and mymodel.DataMappings modules.

Similarly, you can create multiple data model definitions just as you might in a full scale Fins application and configure them similarly. In that situation, you'd pass the model configuration definitions as elements in the mapping passed as the second argument to Fins.Configuration in the example below.

// Fins.FinsModel provides model initialization, so we create a subclass and // prime it with the minimum amount of information required to start up, // namely a faux configuration file that provides details about the model // DataMapping module and SQL connection information. class mymodel {

inherit Fins.FinsModel : fm;

static void create(string sqlurl, int debug, string model_stub_module) { config = Fins.Configuration(0, (["model": (["datasource": sqlurl, "debug": debug, "definition_module": model_stub_module]) ]));

fm::load_model(); } }

int main(int argc, array argv) { // modify the db connection url and the name of the module containing your // model data mapping classes as appropriate. // // you don't need to keep this object around once it's configured the model; // you can access the model through Fins.Model.find and friends or // access the data model context through Fins.DataSources._default object model = mymodel("mysql://blog:pass@localhost/blog", 1, "MTA");

// this line assumes we have a database table called "users" mapped to the User class. werror("%On", values(MTA.Objects.User(1)));

return 0; }

Second example demonstrating multiple model definitions in a standalone application:

class mymodel
{
  inherit Fins.FinsModel : fm;

static void create() { this->config = Fins.Configuration(0, (["model": (["datasource": "sqlite:///db1.sqlite3", "debug": debug, "definition_module": "MTA"]), "model_2": (["datasource": "sqlite:///db2.sqlite3", "id": "second_datasource", "debug": debug, "definition_module": "DataSource2"])

]) );

fm::load_model(); } }

int main(int argc, array argv) { object model = mymodel();

// this line assumes we have a database table called "users" mapped to the User class. werror("%On", values(MTA.Objects.User(1))); // this line assumes we have a database table called "widgets" mapped to the Widget class in our second database. werror("%On", values(DataSource2.Objects.Widget(1)));

object context2 = Fins.DataSources.second_datasource; context2->find->widgets_all();

return 0; }

Not categorized | RSS Feed | BackLinks

comments powered by Disqus