Giter Club home page Giter Club logo

spoof's Introduction

CircleCI Code Climate Test Coverage

spoof

Simple PHP Object Oriented Framework consists of convenient and simple, yet advanced database abstraction layer. It's simple to get started and use, but also packs advanced features.

Installation

In your composer.json make sure you have this repository:

    "repositories": [
        {
            "type": "vcs",
            "url": "https://github.com/unix1/spoof"
        }
    ]

and this package:

    "require": {
        "spoof/spoof": "~0.9"
    }

Basic Usage

connection

Create a PDO connection and add to connection pool with alias test:

use spoof\lib360\db\connection\Config;
use spoof\lib360\db\connection\PDO;
use spoof\lib360\db\connection\Pool;

$conn = new PDO(new Config('mysql:host=localhost;dbname=test', 'root', NULL));
Pool::add($conn, 'test');

select using table factory

This method allows very quick, one-off access to your data.

use spoof\lib360\db\data\TableFactory;

$userTable = TableFactory::get('test', 'users');
$result = $userTable->select();

select using a table class

Defining a table class allows you to define a reusable component instead of using defaults from factory. Below $db is the database alias name, and $name is the table or storage name.

use spoof\lib360\db\data\Table

class UserTable extends Table
{
    protected $db = 'test';
    protected $name = 'users';
}

$userTable = new UserTable();
$result = $userTable->select();

create conditions

Condition objects allow you to define a query restriction that can be reused. The condition object below would read: column user_id equals to integer 5.

use spoof\lib360\db\condition\Condition;
use spoof\lib360\db\value\Value;

$cond = new Condition(
    new Value('user_id', Value::TYPE_COLUMN),
    Condition::OPERATOR_EQUALS,
    new Value(5, Value::TYPE_INTEGER)
);

use condition groups

Condition groups allow you to combine conditions and other condition groups together.

use spoof\lib360\db\condition\ConditionGroup;

$condgroup1 = new ConditionGroup($cond1);
$condgroup1->addCondition(ConditionGroup::OPERATOR_AND, $cond2);

$condgroup1->addCondition(ConditionGroup::OPERATOR_OR, $condgroup2);

use conditions in queries

Condition (or condition group) objects can be easily plugged in select/update/delete statements.

$result = $userTable->delete($condgroup1);

limit returned fields per query

This will select id and name fields only.

$result = $userTable->select($condgroup1, NULL, array('id', 'name'));

limit fields in class definition

This is equivalent of above but defined inside the class as default. You can always override per query.

class UserTable extends Table
{
    protected $db = 'test';
    protected $name = 'user';
    protected $fields = array('id', 'name');
}

$userTable = new UserTable();
$result = $userTable->select($condgroup1);

Advanced Usage

create joins

Let's say you want to display comments made by users; but comments table has the users' ID value, so you want to join against the users table to grab name instead. And you also want to join users table against user_groups to grab their group name.

use spoof\lib360\db\condition\Condition;
use spoof\lib360\db\join\Join;
use spoof\lib360\db\value\Value;

// create condition object linking comments.user_id = users.user_id
$condJoinUsers = new Condition(
    new Value('comments.user_id', Value::TYPE_COLUMN),
    Condition::OPERATOR_EQUALS,
    new Value('users.user_id', Value::TYPE_COLUMN)
);

// create a condition object linking users.group_id = user_group.group_id
$condJoinUserGroup = new Condition(
    new Value('users.group_id', Value::TYPE_COLUMN),
    Condition::OPERATOR_EQUALS,
    new Value('user_group.group_id', Value::TYPE_COLUMN)
);

// create a join object with initial inner join of users and comments tables
$j = new Join('comments', Join::JOIN_TYPE_INNER, 'users', $condJoinUsers);

// add user_group table as a left outer join
$j->addTable(Join::JOIN_TYPE_LEFT_OUTER, 'user_group', $condJoinUserGroup);

create views

Now use the above join inside a view class. Notice you can add as many join objects as desired.

use spoof\lib360\db\data\View;

class UserCommentsView extends View
{
    public function __construct()
    {
        // same join creation code as above resulting in $j object
        // ...

        // add join to array
        $this->joins[] = $j;
    }
}

use views

Views can be used very similar to tables. In fact, they share most of the implementation.

$userComments = new UserCommentsView();

$result = $userComments->select();

There's a lot more! User guides and full documentation are coming soon.

spoof's People

Contributors

unix1 avatar

Stargazers

 avatar

Watchers

 avatar  avatar

spoof's Issues

Allow connection implementations custom configuration parsing

Currently Connection abstract class constructor tries to read the configuration object DSN and parse the driver name and load the driver object.

Issues are:

  • this process might not be the same for all connection implementations.
  • it would be nicer to explicitly allow each implementation an option to perform its own parsing instead of trying to override the constructor

Unit tests must clean up test.db

To repro:

  • run unit tests
    cd lib360
    phpunit
  • look at additional files created
    git status

Expected: no additional files created

Actual: lib360/tests/db/test.db remains

test.db file must be deleted after the test run is completed.

Add ability to transform Model to array

Model class wraps Record, which makes the record array not easily accessible. There should probably be an easy way to transform an instance of a model into an array for output and other external uses.

Rename all $q to $query

Per code climate report, short variable name $q, mostly used in SQL class is too short. Replace it with $query.

Catch/rethrow or let the object\NotFoundException propagate

Currently TODO in Connection::__construct states/asks to implement additional logging when a driver specified in db\Config object is not found. In this case object\Factory throws an object\NotFoundException.

To implement:

  • this should not log anything: remove comment about logging
  • should the Connection object catch and rethrow exception, or let it propagate?

Catching and rethrowing would allow the exception to contain more details about the DSN containing the error.

Get rid of code duplication in PDO class

The executor\PDO class has some code duplication between insert, update, delete, select, and query methods. Create smaller functions to get rid of the code duplication.

Move common test functionality to base test class

Similar to DatabaseTestCase class there should be a base test class containing common base test functionality. First obvious candidate is getProtectedProperty methods spread around individual test classes.

Resolve IValue vs default string types in data classes

The following methods

Table::select
Table::insert
Table::update
Table::delete

expect values to be instances of IValue. However, the following methods:

Table::selectRecord
Table::insertRecord
Table::updateRecord

expect values to be plain strings. Also, when creating conditions and field maps they are hardcoded to strings.

How should this be made consistent? One option is to add automatic type detection to Value class, so it works when data is set to a Record instance too.

NotFoundException interface

Should there be a NotFoundException type that is implemented by both data\RecordNotFoundException and api\ResourceNotFoundException? This would make it easier to capture a general "not found" condition for API response.

Implement models

Model classes should build on existing Table and Record classes to make operating on data easier. User should only need to define a model class, tie it to a table containing a key and a list of fields. Model should take care of all CRUD functions, including operating on lists of data via RecordList.

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.