Graal Forums

Graal Forums (https://forums.graalonline.com/forums/index.php)
-   Code Gallery (https://forums.graalonline.com/forums/forumdisplay.php?f=179)
-   -   Active Record (https://forums.graalonline.com/forums/showthread.php?t=134262561)

fowlplay4 03-26-2011 11:57 PM

Active Record
 
2 Attachment(s)
What is Active Record?
My first experience with active record patterning was with Ruby on Rails, it was amazing to see all the SQL C(reate)R(ead)U(pdate)D(estroy) work disappear. You can read about it more here.

Feel free to ask any questions, comments, etc.

Advantages
- Automatically converts SQL data into their respective Object form
- Handles nearly all SQL business for you
- Dynamic Query Builder
- Easily Implemented

Disadvantages
- A little bit slower than directly implementing SQL due to Object generation, and dynamic query building. I haven't done that much testing but the biggest performance increase comes from disabling SQLite's file sync, after that I was able to create 10000 Objects in one run in 2~ seconds.
- No relationship (I.e: belongs to, has many) support yet, but if there's interest I will go that route.

Example Setup

DB-NPC: Object

PHP Code:

function onCreated() {

  
// DB Migrations
  
this.migrations = {
    {
"new""acct:string""number:integer"}, // Creates Table
    
{"seed"}, // Calls seed()
    
{"add_index""acct""number"},  // Adds Index to Table
    
{"echo""Migrations Completed!"// Optional Message
  
};
  
  
// Configuration
  
  // To Reset DB Set:
  //this.resetdb = true;
  
  // Table Prefix
  //this.table_prefix = "test_";
  
  // Set Exact Table
  //this.table = "some_table_name";
  
  // Model Object's Specific Class
  // Comment out if not-required
  
this.model_class "activerecord_object_" this.name.lower();
  
  
// Model Functionality
  
this.join("activerecord_model");
}

function 
seed() {
  
// Creates some example data
  
for (aallplayers) {
    
this.create({"acct=" a.account"number=" int(random(10000,90000))});
  }
  
// Alert RC
  
echo("Seeded " this.table " with " allplayers.size() @ " entries!");
  
// Successful
  
return true;
}

public function 
validations(obj) {
  
// Model specific validations
  
return true;
}

public function 
relationships() {
  
// Planned in future update if there's interest.
  // I.e: hasmany(objects, through_column)


class: activerecord_object_object

PHP Code:

// Returns the pretty string version of the object
public function pretty() {
  return 
0+this.number SPC this.acct;


Example

Just a small example showcasing the CRUD functionality.

PHP Code:

function onCreated() {
  
test_activerecord();
}

function 
test_activerecord() {
  
// Reset Query Builder
  
Object.reset();
  
// Create
  
for (temp.0temp.10temp.i++) {
    
temp.obj Object.create({"acct=fowlplay4""number=" 0+temp.i});
    
assert_not_null(temp.obj"Object Creation");
  }
  
// Read
  
temp.obj Object.first();
  echo(
temp.obj.pretty());
  
assert(temp.obj.pretty(), "Objects Pretty Method");
  
// Update
  
temp.obj.acct "Shenanigans";
  if (
temp.obj.save()) {
    echo(
"Object saved successfully!");
    
assert_success();
  } else {
    
assert_failure("Object saving");
  }
  
// Dump (Alternate Reading/Debug Function)
  
temp.obj.dump();
  
// Save ID for Verification Later
  
temp.obj_id temp.obj.id;
  
// Destroy
  
temp.obj.destruct();
  
// Verify Destroy
  
temp.obj Object.find(temp.obj_id);
  if (
temp.obj == NULL) {
    echo(
"Object was destroyed");
  }
  
assert_null(temp.obj"Object Destroyed");


Query Builder Example

In activerecord_model

PHP Code:

/*
   Query Building Functions
*/

// Current it just accepts an SQL SELECT clause
// I.e: select("id, name") or select("*")
public function select(args) {
  
this.clause_select args;
  return 
this;
}

// Currently it just accepts an SQL WHERE clause
// I.e: where("id = 3")
public function where(args) {
  
this.clause_where args;
  return 
this;
}

// Currently it just accepts an SQL ORDER BY clause
// I.e: order("name ASC")
public function order(args) {
  
this.clause_order args;
  return 
this
}

// Sets the query to delete mode
// Currently it just accepts an SQL WHERE clause
// I.e: del("id = 3") - Deletes row with id 3
//      del()         - WILL DELETE EVERY ROW IN TABLE
//                      UNLESS where clause specified
public function del(args) {
  
this.clause_delete true;
  if (
args) {
    
this.clause_where args;
  }
  return 
this;
}

// Limits the results retrieved
// It accepts an SQL LIMIT clause OR {startrow, endrow}
// I.e: limit("10")            - Rows 0 - 10
//      limit("10 OFFSET 100") - Rows 100 to 110
//      limit({10, 20})        - Rows 10 to 20
public function limit(args) {
  if (
args.size() == 2) {
    
args int(args[1] - args[0]) SPC "OFFSET" SPC int(args[0]);
  }
  
this.clause_limit args;
  return 
this;
}

/*
   Query Functions
*/

// Returns first result by setting limit to 1
public function first() {
  
this.clause_limit "1";
  return 
this.query();
}

// Returns all results by clearing any limit
public function all() {
  
this.clause_limit "";
  
temp.result this.query();
  return (
temp.result.size() > temp.result.link() : {temp.result});
}

// Resets query building values
// If you're unsure of your current queries clauses
// reset it beforehand.
public function reset() {
  
this.clause_select "";
  
this.clause_limit "";
  
this.clause_where "";
  
this.clause_order "";
  
this.clause_delete "";
  return 
this;
}

// Alias for reset
public function build() {
  return 
this.reset();
}

/*
   Query Aliases
*/

public function get() {
  return 
this.query();
}

public function 
go() {
  return 
this.query();
}

public function 
now() {
  return 
this.query();


Small Example Usage

PHP Code:

function onCreated() {
  
// Find all objects where acct is fowlplay4
  
temp.objs Object.where(format("acct = '%s'"player.account.escape())).all();
  
// Find the first 10 objects
  
temp.objs Object.limit({010}).get();
  
// Delete all objects
  
Object.del().now();



WhiteDragon 03-27-2011 12:09 AM

Good work. I'm personally not a fan of ORM or active records, but on the other hand I don't mind query builders to make writing the simple stuff a little less annoying.

cbk1994 03-27-2011 12:32 AM

Interesting. I've never used something like this but I can see the advantages to it.

Crono 03-27-2011 02:06 AM

lol the 3 guise i wish i had in my university group all postin back 2 back


All times are GMT +2. The time now is 06:14 PM.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2025, vBulletin Solutions Inc.
Copyright (C) 1998-2019 Toonslab All Rights Reserved.