Giter VIP home page Giter VIP logo

granada's Introduction

Granada

Latest Stable Version Build Status

Granada is a easy to use Active Record implementation, and ORM based on Idiorm/Paris.

A quick view:

use Granada\Model;

class User extends Model {
    public function posts() {
        return $this->has_many('Post');
    }
}

class Post extends Model {}


// select
$user = User::where('name', 'John')->find_one();

// modify
$user->first_name = 'Doe';
$user->save();

// select relationship
$posts = $user->posts()->find_many();
foreach ($posts as $post) {
    echo $post->content;
}

You can read the Paris Docs on paris.readthedocs.org but be sure to read the additions below.

Install

Using composer:

  composer require granadaorm/granada

Configure it:

require 'vendor/autoload.php';

use Granada\ORM;

ORM::configure('mysql:host=localhost;dbname=my_database');
ORM::configure('username', 'database_user');
ORM::configure('password', 'top_secret');

As always, you can check it in detail on Paris documentation

Aditions

Eager loading

You can use the "with" method to add relationships eager loading to the query.

  $results = User::with('avatar', 'posts')->find_many();

will use 3 querys to fetch the users and the relationships:

  SELECT * FROM user
  SELECT * FROM avatar WHERE user_id IN (....)
  SELECT * FROM posts WHERE user_id IN (....)

It is possible to get the relationships results for each result, this way

  foreach($results as $result){
      echo $result->avatar->img;
      foreach($result->posts as $post){
         echo $post->title;
      }
  }

Lazy loading

Triying to access to a not fetched relationship will call and return it

  $results = User::find_many();
  foreach($results as $result){
      echo $result->avatar->img;
  }

Notice that if there is no result for avatar on the above example it will throw a Notice: Trying to get property of non-object... Note: Maybe worth the effort to create a NULL object for this use case and others.


Chained relationships with arguments for eager loading!

It is possible to chain relationships and add arguments to the relationships calls

   // chained relationships with dot notation
   $results = User::with('posts.comments')->find_many();

   // OR

   // chained relationships use the "with" reserved word. (usefull if you want to pass arguments to the relationships)
   $results = User::with(array('posts'=>array('with'=>array('comments'))))->find_many();

    // SELECT * FROM user
    // SELECT * FROM post WHERE user_id IN (....)
    // SELECT * FROM comments WHERE post_id IN (....)

   foreach($results as $result){
      foreach($posts as $post){
         echo $post->title;
         foreach($post->comments as $comment){
            echo $comment->subject;
         }
      }
   }


   // you can use arguments (one or more) to call the models relationships
   $results = User::with(array('posts'=>array('arg1')))->find_many();
   // will call the relationship defined in the user model with the argument "arg1"

Custom query filters

It's possible to create static functions on the model to work as filter in queries. Prepended it with "filter_":

use Granada\Model;

class ModelName extends Model {
    ....
    public static function filter_aname($query, $argument1, $argument2...){
        return $query->where('property', 'value')->limit('X')......;
    }
    ....
}

and call it on a static call

ModelName::aname($argument1, $argument2)->....

Multiple additions names for Granada

  • select_raw
  • group_by_raw
  • order_by_raw
  • raw_join
  • insert : To create and save multiple elements from an array
  • pluck : returns a single column from the result.
  • find_pairs : Return array of key=>value as result
  • save : accepts a boolean to use "ON DUPLICATE KEY UPDATE" (just for Mysql)
  • delete_many (accept join clauses)

Overload SET

    // In the Model
    protected function set_title($value)
    {
        $this->alias = Str::slug($value);
        return $value;
    }
    // outside of the model
    $content_instance->set('title', 'A title');

    // works with multiple set too
    $properties = array(
      'title'   => 'A title',
      'content' => 'Some content'
    );
    $content_instance->set($properties);

    // try it with a direct assignement
    $content_instance->title = 'A title';

Overload GET and MISSING property

    // In the Model

    // Work on defined
    protected function get_path($value)
    {
        return strtolower($value);
    }

    // and non-defined attributes.
    protected function mising_testing()
    {
        return 'whatever';
    }
    ...

    // outside of the model
    echo $content_instance->path; // returns the lowercase path value of $content_instance
    echo $content_instance->testing; // returns 'whatever' since we defined a missing_{attribute_name}

Of course, you still can define functions with the property name if you want to overload it completely.


Define resultSet (collection type) class on Model

Now is possible to define the resultSet class returned for a model instances result. (if return_result_sets config variable is set to true) Notice that the resultSet class defined must extends Granada\ResultSet and must be loaded

    // In the Model
    public static $resultSetClass = 'TreeResultSet';
    // outside of the model
    var_dump(Content::find_many());

    // echoes
    object(TreeResultSet)[10]
        protected '_results' => array(...)
    ....

ResultSets are defined by the model in the result, as you can see above. On eager load, the results are consistent. For example, if we have a Content model, with $resultSetClass = 'TreeResultSet' and a has_many relationship defined as media:

  Content::with('media')->find_many();

will return a TreeResultSet with instances of Content each with a property $media containing Granada\ResultSet (the default resultSet if none if defined on the Model)


Basic Documentation comes from Paris:

Paris

Feature complete

Paris is now considered to be feature complete as of version 1.4.0. Whilst it will continue to be maintained with bug fixes there will be no further new features added.

A lightweight Active Record implementation for PHP5.

Built on top of Idiorm.

Tested on PHP 5.2.0+ - may work on earlier versions with PDO and the correct database drivers.

Released under a BSD license.

Features

  • Extremely simple configuration.
  • Exposes the full power of Idiorm's fluent query API.
  • Supports associations.
  • Simple mechanism to encapsulate common queries in filter methods.
  • Built on top of PDO.
  • Uses prepared statements throughout to protect against SQL injection attacks.
  • Database agnostic. Currently supports SQLite, MySQL, Firebird and PostgreSQL. May support others, please give it a try!
  • Supports collections of models with method chaining to filter or apply actions to multiple results at once.
  • Multiple connections are supported

History

Granada was originally developed by Erik Wiesenthal, up to version 1.5. Further development started by Josh Marshall to release version 2.0

granada's People

Contributors

bitdeli-chef avatar j4mie avatar jahvi avatar joshbmarshall avatar kw-pr avatar peterschumacher avatar pine3ree avatar scrutinizer-auto-fixer avatar surt avatar tomvo avatar treffynnon avatar wuffz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

granada's Issues

PHP 8.1: PDO::quote(): Passing null to parameter #1 ($string) of type string is deprecated

I am having null values in my model. In PHP 8.1 I am getting this warning:

Deprecated: PDO::quote(): Passing null to parameter #1 ($string) of type string is deprecated in granadaorm/granada/src/Granada/ORM.php on line 467

Code in ORM::_log_query() looks like this:

$parameters = array_map(array(self::$_db[$connection_name], 'quote'), $parameters);

We would need to quote only parameters not equal null.

Quick fix is to disable logging: ORM::configure('logging', false);

Of course this issue is a very low priority problem at the moment!

Try to change ParisORM to GrandaORM

Thank for fixing the error the class load error on our previous report.

Seem like I find another error.
This library makes it won't automatically find the function based on the camelCase or underscore, in which on the original ParisORM these all are supported function such as :

findMany, findOne and others function.
Message: no static findMany found or static method 'filter_findMany' not defined

Thank you

The model cannot be extended

Hello

I try to extend this model by using this :

// extend default Granada Model ORM
class ORM_Model extends Granada\Model
{

    /**
     * @param int id
     * @param bool array return as
     * @return mixed
     */
    public static function findList(int $id, bool $array = false)
    {
        if (is_null($id)) return false;

        $orm = self::where('id', $id);
        return self::arrayOrObject($array, $orm, $find_many = false);
    }

However this seems not work on the child Class :

class RatihAnggaranORM extends ORM_Model
{
    public static $_table = 'some_table';  
    public static function findList()
    {
        $this->find_many();
    }
}

Use on :

RatihAnggaranORM::where('status', 1)->findList();

This will return the error :
Message: no static findList found or static method 'filter_findList' not defined in RatihAnggaranORM

I also try to remove the static keyword on findList() and it is also not work.
This code previously works perfect on ParisORM when I extend the parisorm base class.

Any suggestion is appreciated.

Thank you.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.