nova-framework / framework

Demo application using Nova - this is an extensive playground, use "app" repository for real applications.
http://novaframework.com/
MIT License
418 stars 210 forks source link

Native database #478

Closed jimgwhit closed 8 years ago

jimgwhit commented 8 years ago

@daveismyname and @LuckyCyborg have you seen the pull request on the fluentpdo github site?
If we are not using doctrine dbal, could we not use these packages either? If everything is written by dave or @LuckyCyborg or @tomvlk then updating the framework will be easier. As of now I have to look for updates in nova and fluentpdo to stay up to date. I know you want to move forward and finalize, but give some thought to it please.

LuckyCyborg commented 8 years ago

@jimgwhit There I'm... :smirk:

jimgwhit commented 8 years ago

@LuckyCyborg in the controller I am just

View::renderPage('index', $data);

my view, index.php

<!DOCTYPE html>
<html lang="<?php //echo LANGUAGE_CODE;  ?>">
    <head>

        <!-- Site meta -->
        <meta charset="utf-8">
        <title>Pets</title>
        <link href="<?php echo site_url('/assets/css/style.css'); ?>" rel="stylesheet">
        <!-- CSS -->

    </head>
    <body>

        <div id="header">

            <a href="<?php echo DIR; ?>pet/index">pet</a>
            <a href="<?php echo DIR; ?>show/index">shows</a>
            <a href="<?php echo DIR; ?>show/add">show add</a>
            <a href="<?php echo DIR; ?>owner/index">owner</a>
            <a href="<?php echo DIR; ?>pet/add">pet add</a>
            <a href="<?php echo DIR; ?>admin/login">login</a>
            <a href="<?php echo DIR; ?>admin/logout">logout</a>

        </div>

        <form method="post" action="<?php echo DIR; ?>pet">
            <label>sch</label><input type="text" name="psch" value=""> <input type="submit" name="submit" value="Search">       
        </form>
        <!--<div class="clear"></div>-->
        <div id="tbl-container">

            <table style="width:94%;">

                <tr>

                    <th style="width:80px;">petname</th>
                    <th style="width:80px;">species</th>
                    <th style="width:80px;">sex</th>
                    <th style="width:80px;">ownerid</th>
                    <th style="width:80px;">petowner</th>
                    <th style="width:80px;">ostreet</th>
                    <th style="width:80px;">odate</th>
                    <th style="width:80px;">ocheck</th>
                    <th style="width:80px;">dogpic</th>
                    <th style="width:80px;">Action</th>
                </tr>

            </table>
            <div class="tblcont2">
                <table>
                    <?php
                    if ($data['pets']) {
                        foreach ($data['pets'] as $row) {
                            echo "<tr>";
                            //echo "<td>" . $row->petid . "</td>";
                            echo "<td style=\"width:80px;\">" . $row['petname'] . "</td>";
                            echo "<td style=\"width:80px;\">" . $row['species'] . "</td>";
                            echo "<td style=\"width:80px;\">" . $row['sex'] . "</td>";
                            echo "<td style=\"width:80px;\">" . $row['ownerid'] . "</td>";
                            echo "<td style=\"width:80px;\">" . $row['petowner'] . "</td>";
                            echo "<td style=\"width:80px;\">" . $row['ostreet'] . "</td>";
                            echo "<td style=\"width:80px;\">" . $row['odate'] . "</td>";
                            echo "<td style=\"width:80px;\">" . $row['ocheck'] . "</td>";

                            if (empty($row['dogpic'])) {
                                echo "<td style=\"width:80px;\">" . "&nbsp;" . "</td>";
                            } else {
                                $linev = '';
                                $linev = '<td><a href="' . DIR . 'upload/' . $row['dogpic'] . '" target="_blank">';
                                $linev = $linev . '<img width="80" border="0"';
                                $linev = $linev . 'src="' . DIR . 'upload/' . $row['dogpic'] . '"></a></td>';
                                echo $linev;
                            }

                            $tmpid = $row['petid'];
                            echo "<td style=\"width:80px;\"><a href='" . DIR . "pet/edit?petid=" . $row['petid'] . "'>Edit2</a>
            <a href='" . DIR . "pet/na/$tmpid'>Delete</a></td>";
                            echo "</tr>";
                        }
                    }
                    ?>
                </table>
            </div>
        </div>

        <?php
        echo '<table style="width:80%;">';
        echo '<tr>';
        echo '<td>' . $data['pageLinks'] . '</td>';
        echo '</tr></table>';
        ?>

    </body>
</html>

And in whatever_site_name/assets/css, I have the various css files, like style.css, styledg.css, stylect.css, etc
Later I will probably make a folder whatever_site_name/assets/headers.
Sorry, I am still confused on the way nova does the headers. My main concern thus far is testing databasing. Maybe eventually I will figure the layout thing out.

jimgwhit commented 8 years ago

Also @daveismyname and @LuckyCyborg see
https://github.com/lichtner/fluentpdo the number of issues and pull request, ikes.

LuckyCyborg commented 8 years ago

@jimgwhit I used from long time FluentPDO and no problems so far.

Do not be so crushed by their issues or pull-requests. It is a well known little project and is as expected they to have activity.

If you worry in this little FluentPDO, then go to CakePHP (the most active project into GitHub), you'll be scared how huge activity they have. :smiling_imp:

tomvlk commented 8 years ago

I don't know the exact content of the issues. But one issue isn't directly a bug.. :laughing:

LuckyCyborg commented 8 years ago

@jimgwhit and @tomvlk Yeah, they propose improvements, discuss.

Also, all we known right? that some love the Scandal Newspaper style titles... :smirk:

jimgwhit commented 8 years ago

@LuckyCyborg all I'm saying is right now if Nova was out already, and when updating Nova manually, you would also have to update fluentpdo, Whereas if all was written internally updating would be easier.

LuckyCyborg commented 8 years ago

@jimgwhit The FluentPDO can be update easily via Composer, like we will do with all other composer packages. :smirk:

But nothing new for an Illuminate, right? :sake:

jimgwhit commented 8 years ago

But how about a forked master of Nova framework, you do your git updating, but that's not going to update Fluentpdo. Prior regular SMVC version 2.2 I would update my master, and simply copy the important files over to production, such as the router, view, URL. Now there's no way to update the master and the fork, because fluentpdo won't be updated, unless Dave keeps it updated in the Nova upstream.
Sure I can update it in the development environment. How do you handle updating on top of an update rather than just one easy to do update? I use github, but just the one single fork and a master.
But how do you update files in your development environment also?
My development environment and my master are not the same.

LuckyCyborg commented 8 years ago

@jimgwhit You talk about how I work at my Office or you want me to fork FluentPDO?

jimgwhit commented 8 years ago

@LuckyCyborg I looked in the composer file, and did not see fluentPDO, so I take it that it is already pre-installed with the framework is that the case? If so my normal way of updating should remain the same. And how do you guys handle updating a real big project on the development end? Like I said the framework has been small enough to simply keep the master updated, and just manually copy and paste the main files I need.
Usually I don't bother updating some of the files that I don't use.
Some of the files in the framework I might have customized, that's why I only update certain files if absolutely necessary, like a security issue. But please share how you guys keep things up to date. This keeping stuff up to date is kinda new to me also.

tomvlk commented 8 years ago

The plan was to use semver for the framework. So patches for every major and minor will be made when it's still in support I suppose.

jimgwhit commented 8 years ago

@tomvlk what is semver ?

LuckyCyborg commented 8 years ago

@jimgwhit The FluentPDO is, of course, into composer.json , take a better look, please!

"lichtner/fluentpdo": "dev-master",

In other hand, the really big projects have their dedicated Administrators, supposed to know everything about the Portal and to maintain it. Daily, hourly, every second.

Or you are suppose that an Portal with 100000 users is shoot into dark, err... into Internet, in some cheappo $15/year and some guy maybe do updates or take a look monthly? :smirk:

The Portals are very very expensive things, both to host them, and as maintenance. :smile:

LuckyCyborg commented 8 years ago

@jimgwhit SEMVER is a style of versioning like 3.0.184, as with major release, release, and micro-release.

For example, Nova probably will be 3.0.0 or 1.0.0, while the first update will be 3.0.1 or 1.0.1.

tomvlk commented 8 years ago

Even more examples.

Stable first version would be 3.0.0. When a bug or security fix is released it would become 3.0.1. When a new release with new features is released it will become 3.1.0. When a new release with breaking changes is released it need to be 4.0.0.

jimgwhit commented 8 years ago

@LuckyCyborg how do you use the query builder simultaneously with built-in Dbal? For example one method in a model you are using dbal and another method you may want to use the query builder. And how do you get set up and going with the querybuilder?

LuckyCyborg commented 8 years ago

@jimgwhit Be more explicit, please!

jimgwhit commented 8 years ago

@LuckyCyborg OK let's start with the query builder, how do you use it. Call it load it, etc

jimgwhit commented 8 years ago

@LuckyCyborg will a use statement at the top of model do the trick or what?

LuckyCyborg commented 8 years ago

@jimgwhit OKay, I undestand...

The QueryBuilder is a instance given on request, from \Nova\Database\Connection, aka the instance returned by \Nova\Database\Manager@getConnection, via getQueryBuilder.

You use it, then this instance die. Every time it give another instance of QueryBuilder.

Long story short, when you want the QueryBuilder, ask nice the Connection for it and Voila!

It is something like:

Give me a QueryBuilder, please!

jimgwhit commented 8 years ago

@LuckyCyborg so can the querybuilder and DBAL be used in the same model, of course different methods? For example use the query builder to select some data and in another method use the DBAL to update some data?

LuckyCyborg commented 8 years ago

@jimgwhit They can be used even in the same Method, because the QueryBuilder instance is built in the top of actual Connection. There is complete compatibility in my Design.

LuckyCyborg commented 8 years ago

@jimgwhit To note that this QueryBuilder supports select, insert, update and delete, then you can work even only with it. :smirk:

LuckyCyborg commented 8 years ago

@jimgwhit BTW, you know that our ORM started working? Look there for its Demo page:

http://smvc3.giulianaeassociati.com/demos/models/orm_model

Now I work on Relations.

jimgwhit commented 8 years ago

@LuckyCyborg how to go from this

this->db->selectAll("SELECT * FROM " .DB_PREFIX ."members WHERE username LIKE :search", array('search' => '%micha%'));

To querybuilder code instead? What needs to be at the top of the model also to make it work?

LuckyCyborg commented 8 years ago

@jimgwhit


$queryBuilder = $this->db->getQueryBuilder();

$queryBuilder
    ->from(DB_PREFIX ."members")
    ->asObject()
    ->where('username LIKE :search', array('search' => '%micha%'))
    ->fetchAll();

Another variant, something more short:


$queryBuilder = $this->db->getQueryBuilder();

$queryBuilder
    ->from(DB_PREFIX ."members")
    ->asObject()
    ->where('username LIKE ?', '%micha%')
    ->fetchAll();
jimgwhit commented 8 years ago

@LuckyCyborg why ->asObject() have to be there? And give me the link please again to the Nova querybuilder syntax Thanks.

LuckyCyborg commented 8 years ago

@jimgwhit Just in case, in case that you have 'array' as default in Configuration and you want objects. Normally, you can leave to Connection to do its job.

http://lichtner.github.io/fluentpdo/

LuckyCyborg commented 8 years ago

@jimgwhit To note the right on the same syntax for WHEREs use also the \Nova\Database nativelly for the update and delete method.

Also, the \App\Core\BaseModel and \Nova\ORM\Model.

jimgwhit commented 8 years ago

@daveismyname and @LuckyCyborg how close is Nova to being finalized? Will the website be the same or different?

LuckyCyborg commented 8 years ago

@jimgwhit From my POV, my colleagues started to write on top of Nova this January, and the only "in progress" component is the \Nova\ORM, which I hope to finish in several days.

In other hand to note our debugging style, as in we like to debug a framework literally using it and seeing how behave into real things.

I can't talk in the name of @daveismyname , of course. But even if him want a release for the next year, in other hand, in the next few months, Nova will starts to pop-up on diverse small sites. :smirk:

jimgwhit commented 8 years ago

@LuckyCyborg and @daveismyname and @tomvlk I see demos for the ORM, but models only could you include models controllers and views in the demo for a better understanding? And later can Docs kinda look like laravel Docs on this, in other words they break the documentation down into each section like this

Database as a link to more detail
Querybuilder
ORM

Each is a link with greater detail and many good examples.

LuckyCyborg commented 8 years ago

@jimgwhit The Examples for ORM which you see are literally introduced into Framework, into Demo Model, for further study.

In other hand, the our native ORM's Model will be literally a MVC Model, ready to be used into Controllers, but it working with Objects and Relations. Think about something like Models with Relations.

Finally, you can use those Model's Relations in the QueryBuilder style:

$model = new Course();

$course = $course->find(1);

$students = $course->students()
    ->where('username != ?', 'tom')
    ->orderBy('address DESC')
    ->limit(20)
    ->offset(40)
    ->get();

To note that the Nova\ORM\Model is not completed, in the final variant will work also the static stile for finders, like:

$course = User::findBy('username', 'jimgwhit');

And guess what, a Model have a Laravel-esque style, for example:

namespace App\Modules\Demo\Models;

use Nova\ORM\Model as BaseModel;

class User extends BaseModel
{
    protected $tableName = 'users';

    protected $relations = array('profile', 'posts');

    public function __construct()
    {
        parent::__construct();
    }

    public function profile()
    {
        return $this->hasOne('App\Modules\Demo\Models\Profile', 'user_id');
    }

    public function posts()
    {
        return $this->hasMany('App\Modules\Demo\Models\Post', 'author_id');
    }

}

Everything have examples into Demo Module.

jimgwhit commented 8 years ago

@LuckyCyborg I have a git fork already of version 2.2 how do I fork 3.0 beta will it be a separate fork altogether? Some of the git stuff is still confusing to me.

LuckyCyborg commented 8 years ago

@jimgwhit Even I'm not a big Git Guru. Usually, I use SVN. How about to fetch upstream?

git fetch upstream
git merge upstream/3.0-beta
jimgwhit commented 8 years ago

@LuckyCyborg about the ORM, how is a primary key delt with that is other than id? For example in laravel model you have

protected $primaryKey = 'ownerid';

so the whole model is

<?php

namespace App;

use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Foundation\Auth\Access\Authorizable;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;

class Powner extends Model implements AuthenticatableContract,
                                    AuthorizableContract,
                                    CanResetPasswordContract
{

    use Authenticatable, Authorizable, CanResetPassword;

    protected $table = 'powners';
    protected $primaryKey = 'ownerid';
    protected $fillable = [
        'ownerid',
        'oname',
        'ostreet',
        'odate',
        'ocheck',
        'ntest'
    ];
    public $timestamps = [];

}

And from there you access the model from controller something like

$mydata = Powner::find(4);

How does this compair to nova orm?

LuckyCyborg commented 8 years ago

@jimgwhit There is also a $primaryKey, configurable similar. Just use as:

protected $primaryKey = 'ownerid';

In other hand, the static access to finding methods is not yet implemented. But I have intention to. In the mean time you can use:

$model = new Powner();

$owner = $model->find(4);

The $owner is a hydrated instance of Powner, while a non-hydrated instance ($model) act as Model.

LuckyCyborg commented 8 years ago

@jimgwhit And I finished the belongToMany's Pivot...

So, right now you can have pages with Many friendly dogs play with Many kids... ;smirk:

Now I will implement the static calling part...

jimgwhit commented 8 years ago

@LuckyCyborg but the main question was dealing with primary IDs

protected $primaryKey = 'ownerid';

If the primary key isn't I'd. What is the proper way to deal with that?

LuckyCyborg commented 8 years ago

@jimgwhit As in your primaryKey is not an integer(11)?

jimgwhit commented 8 years ago

@LuckyCyborg no primary key is an integer but not called ID So how do you deal with a primary key with a name other than ID ? Like the primary key is called ownerid.

LuckyCyborg commented 8 years ago

@jimgwhit Just similar like in a Laravel Model, into your Model you add that line:

protected $primaryKey = 'ownerid';
jimgwhit commented 8 years ago

@LuckyCyborg what is an examples link for orm? Is it even ready to test yet?

LuckyCyborg commented 8 years ago

@jimgwhit There is where I have my test website:

http://smvc3.giulianaeassociati.com/demos/models/orm_model

jimgwhit commented 8 years ago

Does this part go in controller

$mydata = Powner->find(4);

Then of course view would be called.
And a use statement for the model needed in controller correct?

LuckyCyborg commented 8 years ago

@jimgwhit In a Controller is more simple: just use the Model as... Model, in Constructor.

Then you access its methods as:

$this->model->find(4);
jimgwhit commented 8 years ago

@LuckyCyborg where how is $this->model assigned and why not Powner->find I will study demo more.

nekomajin commented 8 years ago

@jimgwhit

I have a git fork already of version 2.2 how do I fork 3.0 beta will it be a separate fork altogether? Some of the git stuff is still confusing to me.

1. Configuring a remote for a fork

Example: git remote add smvc_master https://github.com/simple-mvc-framework/framework.git

2. List the current configured remote repository for your fork.

git remote -v

Output:

smvc_master https://github.com/simple-mvc-framework/framework.git (fetch)
smvc_master https://github.com/simple-mvc-framework/framework.git (push)

3. Syncing a fork

git fetch smvc_master OR git pull smvc_master (include merge of all changes in the master branch)

4. Create a Traking Branch

Example: git checkout -b 3.0-beta smvc_master/3.0-beta

5. Everytime for changes from @LuckyCyborg, @tomvlk or @daveismyname (and from time to time @nekomajin)

git pull 3.0-beta

and you will stay up-to-date with the 3.0 beta branch :thumbsup: :blush:

LuckyCyborg commented 8 years ago

@jimgwhit remember that it is a Model. A MVC Model. Here I will do an example:

use App\Models\Dog;

class Dogs extends BaseController
{
    protected $model;

    public function __construct() 
    {
        parent::__construct();

        $this->model = new Dog();
    }

    public function find()
    {
        $dog = $this->model->find(4);

        ...
    }

    public function findDog()
    {
        $model = new Dog();

        $dog = $model->find(4);

        ...
    }
}