Giter Site home page Giter Site logo

paris's Introduction

Paris

Build Status Latest Stable Version Total Downloads

https://j4mie.github.io/idiormandparis/


In maintenance only mode

Idiorm and Paris are now considered to be feature complete as of version 1.5.0. Whilst they will continue to be maintained with bug fixes there will be no further new features added from this point on. This means that if a pull request makes breaking changes to the API or requires anything other than a patch version bump of the library then it will not be merged.

Please do not submit feature requests or API breaking changes as they will be closed without ceremony.

Should I use Idiorm/Paris?

If you're starting a new project

It is not recommended that you use either Idiorm or Paris in new projects.

I recommend that you use the Eloquent database library from Laravel as Taylor based it on Idiorm when he wrote it. This means that many of the same ideas are present there, but it is more actively maintained and has a more modern code style.

If you have existing projects based on Idiorm or Paris

You can continue to use both projects as they will continue to receive security patches and bug fixes. It is important to note that future versions of PHP may not be supported if changes they require would break backwards compatibility.

At this point you can either use another database library such as Eloquent from Laravel (see If you're starting a new project above) or you could decide to fork Idiorm and/or Paris to patch them with your own modifications.

But, why?

For further information on the state of this project please see j4mie/idiorm#360


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

Documentation

The documentation is hosted on Read the Docs: paris.rtfd.org

Building the Docs

You will need to install Sphinx and then in the docs folder run:

make html

The documentation will now be in docs/_build/html/index.html

Let's See Some Code

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

class Tweet extends Model {}

$user = Model::factory('User')
    ->where_equal('username', 'j4mie')
    ->find_one();
$user->first_name = 'Jamie';
$user->save();

$tweets = $user->tweets()->find_many();
foreach ($tweets as $tweet) {
    echo $tweet->text;
}

Changelog

1.5.6 - released 2017-03-21

  • Allow IDE's to autocomplete when foreach over find_many() result [stratoss] - issue #128
  • Document the @property PHPDoc comment for IDE autocomplete of model properties [Treffynnon]

1.5.5 - released 2016-12-14

  • Fix join table name not generated correctly [Ralphunter] - issue #109
  • Add phpunit as dev dependency and composer script (composer test) to easily run tests [Treffynnon]
  • Global setting to allow static requests to avoid being forced in to using the namespace + class as the auto table name [michaelward82] - issue #100
  • Document conflict between static Model calling and auto_prefix_models [michaelward82] - issue #102
  • Added @method tags for magic methods [stellis] - issue #104
  • Add missing __unset() magic method [qyanu] - issue #106
  • Remove PHP 5.2 from travis-ci containers to test against (note Idiorm still supports PHP 5.2 despite this) [Treffynnon]

1.5.4 - released 2014-09-23

1.5.3 - released 2014-06-25

  • Remove erroneously committed git merge backup file

1.5.2 - released 2014-06-23

  • Paris incorrectly relying on old Idiorm version in the composer.json [ilsenem] - issue #96

1.5.1 - released 2014-06-22

  • Remove HHVM build target from travis-ci as there is a bug in HHVM

1.5.0 - released 2014-06-22

1.4.2 - released 2013-12-12

Patch update to remove a broken pull request - may have consequences for users of 1.4.0 and 1.4.1 that exploited the "find_many() now returns an associative array with the databases primary ID as the array keys" change that was merged in 1.4.0.

  • Back out pull request/issue #133 as it breaks backwards compatibility in previously unexpected ways (see Idiorm issues #162, #156 and #133) - sorry for merging this change into Paris - closes Idiorm issue 156

1.4.1 - released 2013-09-05

1.4.0 - released 2013-09-05

  • Call methods against model class directly eg. User::find_many() - PHP 5.3 only [Lapayo] - issue #62
  • find_many() now returns an associative array with the databases primary ID as the array keys [Surt] - see commit 9ac0ae7 and Idiorm issue #133
  • Add PSR-1 compliant camelCase method calls to Idiorm (PHP 5.3+ required) [crhayes] - issue #59
  • Allow specification of connection on relation methods [alexandrusavin] - issue #55
  • Make tests/bootstrap.php HHVM compatible [JoelMarcey] - issue #71
  • belongs_to doesn't work with $auto_prefix_models (issue #70)

1.3.0 - released 2013-01-31

  • Documentation moved to paris.rtfd.org and now built using Sphinx
  • Add support for multiple database connections [tag] - issue #15
  • Allow a prefix for model class names - see Configuration in the documentation - closes issues #33
  • Exclude tests and git files from git exports (used by composer)
  • Implement set_expr - closes issue #39
  • Add is_new - closes issue #40
  • Add support for the new IdiormResultSet object in Idiorm - closes issue #14
  • Change Composer to use a classmap so that autoloading is better supported [javierd] - issue #44
  • Move tests into PHPUnit to match Idiorm
  • Update included Idiorm version for tests
  • Move documentation to use Sphinx

1.2.0 - released 2012-11-14

  • Setup composer for installation via packagist (j4mie/paris)
  • Add in basic namespace support, see issue #20
  • Allow properties to be set as an associative array in set(), see issue #13
  • Patch in idiorm now allows empty models to be saved (j4mie/idiorm see issue #58)

1.1.1 - released 2011-01-30

1.1.0 - released 2011-01-24

  • Add is_dirty method

1.0.0 - released 2010-12-01

  • Initial release

paris's People

Contributors

alexandrusavin avatar j4mie avatar jahvi avatar joelmarcey avatar kkeiper1103 avatar lapayo avatar naga3 avatar ptarjan avatar rhynodesigns avatar rotexdegba avatar stellis avatar stratoss avatar surt avatar treffynnon avatar

Stargazers

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

Watchers

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

paris's Issues

Composite Key association

I have table which has composite primary key. How would I associate this table by using has_one function.

for e.g
I have a product and product_description table. product_description contains multiple description with language information. But it create one-to-one association with product. product_description has product_id and language_id as composite primary key.

$_table static not used in associations

I have declared a has_many / belongs_to association, and i get the error that my table doesn't exist. I have declared the table name in the static $_table variable, but it doesn't use it to figure out the name of the correct table, instead it uses the default, classname.

How can I use multiple connections with relation functions

I made a simple patch that solves a problem that I stumbled upon while working with multiple connections.

I have relations through different databases and thus I have a lot of connections configured but when I tried to create the helper functions (in the model classes) for this relations I was getting "unknown PDO driver" error caused by the self::factory function, used in _has_one_or_many. It was using the default connection so I guess it should also get a variable for the connection name.

Here is a gist with the patch: https://gist.github.com/savinzoobe/5364083

Am I doing something wrong or is this really an issue?

Dealing with logic in models [question]

How would you go about using a Paris model as a model containing methods that return objects of itself. Say I have a method that creates an array of Paris objects by some advanced algorithm, where should I put this? (think along the lines of find_by_*) You advice to make a method return an array of newly created objects of itself?

Packagist idiorm dependency

It seems I'm unable to install paris using composer, because it depends on j4mie/idiorm 1.3.* :

./composer.phar update -v
Loading composer repositories with package information
Updating dependencies
Your requirements could not be resolved to an installable set of packages.

Problem 1

  • Installation request for j4mie/paris dev-master -> satisfiable by j4mie/paris dev-master.
  • j4mie/paris dev-master requires j4mie/idiorm 1.3.* -> no matching package found.

Any gotchas I'm missing? TIA.

composer.json:

{
    "require": {
        "j4mie/idiorm": "dev-master",
        "j4mie/paris": "dev-master"

    },

  "config" : {
         "vendor-dir" : "packages"
    },
    "minimum-stability": "dev"
}

Don't force objects to always pre-load (per composer.json)

Paris should autoload when needed, rather than forced to load on every page request (as set in composer.json). This occurs because of the "files" key. See the relevant Composer documentation section for more info.

Better autoloading can be accomplished by renaming ./paris.php to (for example) ./src/Model.php, and modifying composer.json:

    "autoload": {
        "psr-0": {
            "Model": "src/"
        }
    }

This simple approach assumes OrmWrapper is used only as an internal class, and not accessed directly (unless Model is loaded first).

@kevinsperrine has a forked version that can be used as an example.

Similar changes should be made to Idiom's composer.json.

Associations?

Are associations on the roadmap? If so, what level of complexity are you shooting for? etc.

Migration support (schema/table from model code)

I'm wondering if migrations will eventually be added to Paris/Idiorm? It would really be nice if we could be saved from having to create schema files and just design everything through our models. Thanks.

Order Results?

Would it be possible to order the results of a Paris query?
I'm not sure if I am overlooking something hideously obvious... but it seems that this is not currently possible.

Can somebody fill me in?

(ps, awesome work j4mie!)

Missing functions

Hi

when create() has been called, is there a way to check if the given object is a new object?

In idiorm there is a new function 'set_expr' but it's not implemented in paris.

Regards,

Add support for find_array() to Paris models

Using 1.2.0 in my app I have a model like this:

class Config extends Model {
   public static $_table = 'Sites';
}

When I call a find_array it does not use the table information

    $config = Model::factory('Config')->where('id',$siteId)->find_array();

Error is that table config doesn't exist. If I add the for_table('Sites') method, it works.

Validation?

Will validation be implemented? There are a couple of different kinds: built-in automatic rules based on database schema (e.g. required values for "not null" fields, max lengths for VARCHAR sizes, integers for INT fields, etc.), and also systems for adding your own rules via callbacks.

Quick question

I dont think this is an issue but only place i could ask.
I using Paris and created a model order when I insert a record how can I get the last insert id? can that be done from paris or do I need to use idiorm?
Thanks in advance any help you can provide

I'm currently using PostgreSql

type matching

Is it planed to work on type matching between sql and php ?

for exemple translate sql timestamp in php datetime ?

Slowness on save after find_many

I have the following code in a script. The intention is to retrospectively hash all of the passwords in a user table.

namespace {

    # Autoload composer included libraries
    require 'vendor/autoload.php';

    ORM::configure('mysql:host=127.0.0.1;dbname=dbname');
    ORM::configure('username', 'user');
    ORM::configure('password', 'password');

    // User class
    class User extends Model
    {
    }

    function getUnhashedPasswordUsers($limit = 1000)
    {
        $nullPasswordValue = hex2bin('000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000');

        $users = Model::factory('User')
            ->where('password_hash', $nullPasswordValue)
            ->limit($limit)
            ->find_many();

        return $users;
    }

    function hashPasswords()
    {
        $users = getUnhashedPasswordUsers(1);

        if (count($users) > 0) {
            foreach ($users as $user) {
                $hash = password_hash($user->password, PASSWORD_DEFAULT);

                echo $user->password . " = $hash\n";

                $user->password_hash = $hash;
                $user->save();

                return true;
            }
        } else {
            return false;
        }
    }

    $notDoneHashing = true;
    while ($notDoneHashing) {
        $notDoneHashing = hashPasswords();
    }

    echo "finished";
}

The problem I have is that the more results the query returns, the more the script slows down on each iteration of the foreach loop.

The user query seems to run quickly enough, the slowdown appears to occur on save.

Is the entire set being saved on each iteration, or is there another explanation for the slowdown?

Creating record where no record matches

I'm not sure exactly what is causing this. On my MySQL table parent_id, child_id, child_table combined are a unique key. Then

$rel = Model::factory("Relations")->where("child_id", $childId)
                                        ->where("child_table", $childTable)
                                        ->where("parent_id", $parentId)
                                        ->find_one();

always creates a new row where a matching record doesn't already exist.

Quoted wildcards in associations

Good afternoon,

I'm building a couple of projects that back on to idiorm/paris at the moment, and I seem to have hit a bug in the code that manages associations between Models. Essentially, when I attempt a "has_many_through()" call that should succeed, PDO throws an exception that indicates that somewhere along the line, something is quoting the SQL query incorrectly.

At some point, the system attempts a "SELECT table.* FROM table JOIN...", which is quoted as "table"."*", which fails because * is not a recognised column in that table. I can reproduce the bug in both MySQL and PostgreSQL (where both libraries otherwise perform very well, incidentally).

Example code can be found at my friend Aquarion's server, here: http://cenote.gkhs.net/~aquarion/idiormtest/ - that's running on MySQL.

We suspect, as the URL indicates, that the bug itself is likely in idiorm, but we're only really seeing its effects through paris. Feel free to move this issue to the idiorm issue-list if you prefer, of course.

Drop PHP5.2 support requirement

Remove the requirement for Idiorm to be 5.2 compatible.

See the comments on Idiorm issue #78 for more information on why this must take place.

This will affect a small number of users hopefully, but if there is a major backlash then I am not averse to leaving this requirement drop til version 3. Please discuss.

Support inserting/updating models via has_many_through relationships

While Paris supports querying related models through "Associations," it is less simple and straightforward to update or manipulate those models, particularly for many-to-many relationships.

Laravel's ORM provides this functionality, which we could replicate in Paris with a very similar API.

Using the example in Paris' documentation, we can do

$book = Model::factory('Book')->find_one($book_id);
$authors = $book->authors()->find_many();
$first_author = $authors[0];

But we cannot do

$newAuthor = Model::factory('Author')->create();
$newAuthor->name = "Mark Twain";
$authors->insert($newAuthor);

This problem can be side-stepped by creating and inserting an instance of the intermediate model (AuthorBook), although this seems to be exactly the kind of chore than an ORM is supposed to relieve us from having to do in our applications.

additional non-database properties in the model

Hi Jamie!

I come up lately with the following question, when I tried to put my (form) validation into the model class:
How is it possible to add class member variables, which are not mapped to a database field, so I get no errors on save().

Imagine a form with e.g. a checkbox where the user has to accept the terms and conditions before submitting. This checkbox is just like every other form field an input field with name and value, which has to be validated on the backend side. So I would like to add this field to the model to have it present for validation, but I don't want it to be mapped to a real database field, cause I don't need to save this information as every database row would a value of 'true' for that field, which is just not necessary.

Regards,
Matthias

Where clause with array param

I think that can be a good thing to permit make one single call to the where method for multiple conditions. Something like that :

public function where($column_name, $value = null) {
    if(is_array($column_name)){
        $self = $this;
        foreach($column_name as $key=>$value){
            $self = $self->where_equal($key, $value);
        }
        return $self;
    } else {
        return $this->where_equal($column_name, $value);
    }
}

Remove tests from deployed composer package

The composer documentation suggests not exporting tests or other unnecessary files when deploying (e.g., via Packagist).

Per the Composer documentation, this can be accomplished by adding a .gitattributes file, with something like:

/test export-ignore

Feature rq: Model->setId() and isDirty([field])

Hi, J4mie!

After some time back to my IdiORM-izing and Paris-ing code, I found two things to be useful:

(1) setId() instance method for Model (helpful if working with legacy database, with quite randomly named primary key columns):
this one cannot be implemented in clean way by extending Model class as Model::orm->_get_id_column_name() is protected, so I ended up with:

public function setId($id) {
   $idColumn = self::_get_id_column_name(get_class());
   return $this->set($idColumn, $id);
}

(2) method(-s) to check, whether given field or any fields of Model object are dirty (changed by set())

Thanks for the good job!

build query after execution of query

Hi, there

I really appreciate your work first of all.
Just suggestions.
when i start to use the model.

$types = Model::factory('type')->where_lt('type_id', 20);
$count_1 = $types->count();
$count_2 = $types->where_gt('parent_premise_type_id', 100)->count();
// errors

or

$types = Model::factory('type')->where_lt('type_id', 20)->order_by_asc('type_id');
$count_1 = $types->count();
//other different errors....

Sometimes I just want to build a new query based on previous query after execution of previous query.
But I can't.
I have to build the previous query again.
Those functions (count(), find_many(), find_one()) seem to set up a global query. Each execution will just update that global query based on previous execution, not rebuild.

I know I can create a funtion which builds the based query. Then use that function repeatly.
But might be better just rebuild/execute the global query using the criterion arrays when find_many()/find_one()/count(). It's more convenient.

Cheers

Implement JsonSerializable

Is there any chance that Paris could implement the JsonSerializable interface that was introduced in PHP 5.4.0?

This would allow us to call json_encode() on our models, and have everything behave as expected.

Version of PHP?

Absolutely loving Paris/Idiorm so far, I've been hunting for an Ruby Active Record-like thing for PHP for a while, and this is like an oasis in the desert.

But I had a question, what version of PHP do they require? I'm on 5.3 on my dev box, but would need to deploy to 5.2.

I'll go ahead and test it, but it is probably worth putting the requirements in the README.

Cheers,
p.

table name pluralization

This might be more complicated than you want to get with the library, but automatically pluralizing model names to map to table names makes more sense from an "end-user" point of view -- I think that's what most people expect with ActiveRecord.
Perhaps you could "borrow" some code from another AR library, for example, Kohana3:
http://github.com/kohana/core/blob/3.0.x/classes/kohana/inflector.php

Note that this gets tricky with join tables of has_many_through relationships (author_books vs. authors_books).

Question/Request: found() function

I'm trying to return an error if a where() call returns zero records, but Paris creates an object instead, with field defaults. Should it not return an empty object instead?

Is there some kind of functionality I'm missing? Or is this more an idea for Idiorm? Or something more basic?

Inheritance support

Is there a simple way to implement inheritance? I've a view that mix content from three tables and I have no idea how associate de content to their respective classes.

how to order a query?

I'm having some problems, I can't find anywhere on the docs how to order a query;

Can anyone help me?

Hacking associations

Hi! i need help...

I modified paris __get magic method with this:

    public function __get($property) {
        if (method_exists($this, $property)) {
            return call_user_func(array($this, $property));
        }
        return $this->orm->get($property);
    }

and the example of profile belong_to to this:

class Profile extends Model {
    public function user() {
        return $this->belongs_to('User')->find_one();
    }
}

This is good for this call $user = $profile->user; echo $user->name;
But have problems with this another echo $profile->user->name

Have any idea what could be the problem? syntax looks cool!

Regards,
Jordi

README could use a mysql connection example

Might be helpful to include a connection string example for mysql (or any database that requires a username and password), eg:
ORM::configure('connection_string', 'mysql:dbname=mydatabase;host=localhost');
ORM::configure('username', 'myusername');
ORM::configure('password', 'mypassword');
(will save people a few minutes of looking through code)

has_many_through(...) does not support model prefixes

has_many_through(...) does not support model prefixes. As a result, default table names are used when working with models with a prefix and an overwritten table name.

Models:

class Model_User extends Model {
    public static $_table = 'app_user';
    public function groups() {
        return $this->has_many_through('Group', 'UserGroup', 'user_id', 'group_id');
    }
}
class Model_Group extends Model {
    public static $_table = 'app_group';
}
class Model_UserGroup extends Model {
    public static $_table = 'app_usergroup';
}

Example:

$user = Model::factory('User')->find_one();
$groups = $user->groups()->find_many();

Resulting query:

SELECT `group`.* FROM `app_group` JOIN `usergroup` ON `group`.`id` = `usergroup`.`group_id` WHERE `usergroup`.`user_id` = ?

Expected:

SELECT `app_group`.* FROM `app_group` JOIN `app_usergroup` ON `app_group`.`id` = `app_usergroup`.`group_id` WHERE `app_usergroup`.`user_id` = ?

extendig ORMWrapper

Also, I wonder, what would be the correct and least "hacking" way to extend ORM instance, wrapped in Model classes?

We have Postgres behind and in subclass of Model, from which all our application models derive from, I would like to modify _build_insert() method (protected) - to be

INSERT (..) VALUES (..) RETURNING id_column

Move documentation out of one massive readme file

The documentation is a little unmanageable so it will be moved to a Sphinx setup hosted on readthedocs.

A new branch has been started for this work called sphinxdocs.

This project is already setup on Read the Docs and will begin working at paris.readthedocs.org when it is merged into the master branch.

pgsql driver returns oid instead of id after save()

$obj->save();
echo $obj->id; // show the row oid

I know that exist an annoying problem in PDO pgsql driver that required the sequence name in lastInsertId() method. The sequence ID often has a column-based default name that can be used here, right?

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.