- fixed a Bug with wrong character information in logs when system get deleted

- removed Unit tests for "Cortex" F3 extension
This commit is contained in:
Mark Friedrich
2017-12-04 21:21:45 +01:00
parent f3ad8fb7ea
commit d0996c8a83
11 changed files with 10 additions and 1943 deletions

View File

@@ -1,54 +0,0 @@
<?php
namespace App;
class Cortex extends Controller
{
function get()
{
$f3 = \Base::instance();
$f3->set('AUTOLOAD', $f3->get('AUTOLOAD').';app/cortex/');
$f3->set('QUIET', false);
$dbs = array(
'sql' => new \DB\SQL('mysql:host=localhost;port=3306;dbname=fatfree', 'fatfree', ''),
// 'sql-sqlite' => new \DB\SQL('sqlite:data/sqlite.db'),
// 'sql-pgsql' => new \DB\SQL('pgsql:host=localhost;dbname=fatfree', 'fatfree', 'fatfree'),
'jig' => new \DB\Jig('data/'),
'mongo' => new \DB\Mongo('mongodb://localhost:27017', 'testdb'),
// 'sqlsrv2012' => new \DB\SQL('sqlsrv:SERVER=LOCALHOST\SQLEXPRESS2012;Database=fatfree','fatfree', 'fatfree'),
// 'sqlsrv2008' => new \DB\SQL('sqlsrv:SERVER=LOCALHOST\SQLEXPRESS2008;Database=fatfree','fatfree', 'fatfree'),
);
$results = array();
// Test Syntax
foreach ($dbs as $type => $db) {
$test = new \Test_Syntax();
$results = array_merge((array) $results, (array) $test->run($db, $type));
}
// Test Relations
foreach ($dbs as $type => $db) {
$f3->set('DB',$db);
$test = new \Test_Relation();
$results = array_merge((array) $results, (array) $test->run($db, $type));
}
// Test Filter
foreach ($dbs as $type => $db) {
$f3->set('DB',$db);
$test = new \Test_Filter();
$results = array_merge((array) $results, (array) $test->run($db, $type));
}
// Further Common Tests
if (isset($dbs['sql'])) {
$test = new \Test_Common();
$f3->set('DB', $dbs['sql']);
$results = array_merge((array) $results, (array) $test->run());
}
$f3->set('results', $results);
}
}

View File

@@ -1,27 +0,0 @@
<?php
class AuthorModel extends \DB\Cortex {
protected
$fieldConf = array(
'name' => array(
'type' => \DB\SQL\Schema::DT_VARCHAR256
),
'mail' => array(
'type' => \DB\SQL\Schema::DT_VARCHAR256
),
'website' => array(
'type' => \DB\SQL\Schema::DT_VARCHAR256
),
'news' => array(
'has-many' => array('\NewsModel','author'),
),
'profile' => array(
'has-one' => array('\ProfileModel','author'),
),
),
// $primary = 'aid',
$table = 'author',
$db = 'DB';
}

View File

@@ -1,28 +0,0 @@
<?php
class NewsModel extends \DB\Cortex {
protected
$fieldConf = array(
'title' => array(
'type' => \DB\SQL\Schema::DT_VARCHAR128
),
'text' => array(
'type' => \DB\SQL\Schema::DT_TEXT
),
'author' => array(
'belongs-to-one' => '\AuthorModel',
),
'tags' => array(
'belongs-to-many' => '\TagModel',
),
'tags2' => array(
'has-many' => array('\TagModel','news','news_tags'),
// 'has-many' => array('\TagModel','news'),
),
),
// $primary='nid',
$table = 'news',
$db = 'DB';
}

View File

@@ -1,21 +0,0 @@
<?php
class ProfileModel extends \DB\Cortex {
protected
$fieldConf = array(
'message' => array(
'type' => \DB\SQL\Schema::DT_TEXT
),
'image' => array(
'type' => \DB\SQL\Schema::DT_VARCHAR256
),
'author' => array(
'belongs-to-one' => '\AuthorModel'
)
),
// $primary = 'profile_id',
$table = 'profile',
$db = 'DB';
}

View File

@@ -1,18 +0,0 @@
<?php
class TagModel extends \DB\Cortex {
protected
$fieldConf = array(
'title' => array(
'type' => \DB\SQL\Schema::DT_VARCHAR128
),
'news' => array(
'has-many' => array('\NewsModel','tags2','news_tags'),
),
),
// $primary = 'tid',
$table = 'tags',
$db = 'DB';
}

View File

@@ -1,125 +0,0 @@
<?php
use App\Controller;
class Test_Common {
function run()
{
$test = new \Test();
/** @var \Base $f3 */
$f3 = \Base::instance();
$news = new NewsModel();
$news->load();
$dummy = array(
'title'=>'copy test',
'text'=>'Lorem ipsum dolor sit amet.',
'author'=>1,
'tags'=>array(3)
);
$f3->set('record1', $dummy);
$news->copyto('record2');
$test->expect(
$f3->exists('record2'),
'copyto: raw record copied to hive'
);
$news->reset();
$news->copyfrom('record1');
$test->expect(
$news->title = 'copy test' &&
$news->text = 'Lorem ipsum dolor sit amet.',
'copyfrom: hydrate from hive key'
);
$test->expect(
$news->author instanceof AuthorModel
&& !$news->author->dry() &&
$news->tags instanceof \DB\CortexCollection,
'copyfrom: relations hydrated successful'
);
$test->expect(
$news->get('author',true) == 1,
'get raw data from relational field'
);
$news->reset();
$news->copyfrom('record2','title;author');
$test->expect(
$news->title = 'Responsive Images' &&
$news->get('author',true) == 2 &&
$news->text == NULL,
'copyfrom: limit fields with split-able string'
);
$news->reset();
$news->copyfrom('record2',array('title'));
$test->expect(
$news->title = 'Responsive Images' && $news->text == NULL,
'copyfrom: limit fields by array'
);
$news->reset();
$news->copyfrom($dummy,function($fields) {
return array_intersect_key($fields,array_flip(array('title')));
});
$test->expect(
$news->title = 'copy test',
'copyfrom: copy from array instead of hive key'
);
$test->expect(
$news->title = 'copy test' && $news->text == NULL,
'copyfrom: limit fields by callback function'
);
$all = $news->find();
$allTitle = $all->getAll('title');
$test->expect(
count($allTitle) == 3 &&
$allTitle[0] == 'Responsive Images' &&
$allTitle[1] == 'CSS3 Showcase' &&
$allTitle[2] == 'Touchable Interfaces',
'collection getAll returns all values of selected field'
);
$newsByID = $all->getBy('_id');
$test->expect(
array_keys($newsByID) == array(1,2,3),
'collection getBy sorts by given field'
);
$newsByAuthorID = $all->getBy('author',true);
$test->expect(
array_keys($newsByAuthorID) == array(2, 1) &&
count($newsByAuthorID[2]) == 2 &&
count($newsByAuthorID[1]) == 1,
'collection getBy nested sort by author'
);
$allTitle = array();
foreach($all as $record)
$allTitle[] = $record->title;
$test->expect(
count($allTitle) == 3 &&
$allTitle[0] == 'Responsive Images' &&
$allTitle[1] == 'CSS3 Showcase' &&
$allTitle[2] == 'Touchable Interfaces',
'collection is traversable'
);
///////////////////////////////////
return $test->results();
}
}

View File

@@ -1,302 +0,0 @@
<?php
use App\Controller;
class Test_Filter {
function run($db,$type)
{
$test = new \Test();
// setup
///////////////////////////////////
$author = new \AuthorModel();
$news = new \NewsModel();
$profile = new \ProfileModel();
$tag = new \TagModel();
$ac=$author::resolveConfiguration();
$author_pk = (is_int(strpos($type,'sql'))?$ac['primary']:'_id');
$nc=$news::resolveConfiguration();
$news_pk = (is_int(strpos($type,'sql'))?$nc['primary']:'_id');
$tc=$tag::resolveConfiguration();
$tag_pk = (is_int(strpos($type,'sql'))?$tc['primary']:'_id');
$authorIDs = $author->find()->getAll('_id');
$all = $news->find();
$newsIDs = $all->getAll('_id');
$profileIDs = $profile->find()->getAll('_id');
$tagIDs = $tag->find()->getAll('_id');
// add another relation
$news->load(array('title = ?','CSS3 Showcase'));
$news->author = $author->load(array($author_pk.' = ?',$authorIDs[0]));
$news->save();
$news->reset();
$author->reset();
// has-filter on belongs-to relation
///////////////////////////////////
$result = $author->has('news', array('title like ?', '%Image%'))->afind();
$test->expect(
count($result) == 1 &&
$result[0]['name'] == 'Johnny English',
$type.': has filter on many-to-one field'
);
$test->expect(
count($result[0]['news']) == 2 &&
$result[0]['news'][0]['title'] == 'Responsive Images' &&
$result[0]['news'][1]['title'] == 'CSS3 Showcase',
$type.': has filter does not prune relation set'
);
$result = $news->has('author', array('name = ?', 'Johnny English'))->afind();
$test->expect(
count($result) == 2 && // has 2 news
$result[0]['title'] == 'Responsive Images' &&
$result[1]['title'] == 'CSS3 Showcase',
$type.': has filter on one-to-many field'
);
// add another profile
$profile->message = 'Beam me up, Scotty!';
$profile->author = $authorIDs[2];
$profile->save();
$profile->reset();
$result = $author->has('profile',array('message LIKE ?','%Scotty%'))->afind();
$test->expect(
count($result) == 1 &&
$result[0]['name'] == 'James T. Kirk' &&
$result[0]['profile']['message'] == 'Beam me up, Scotty!',
$type.': has filter on one-to-one field'
);
$result = $profile->has('author',array('name LIKE ?','%Kirk%'))->afind();
$test->expect(
count($result) == 1 &&
$result[0]['message'] == 'Beam me up, Scotty!' &&
$result[0]['author']['name'] == 'James T. Kirk',
$type.': has filter on one-to-one field, inverse'
);
// add mm tags
$news->load(array('title = ?','Responsive Images'));
$news->tags2 = array($tagIDs[0],$tagIDs[1]);
$news->save();
$news->load(array('title = ?','CSS3 Showcase'));
$news->tags2 = array($tagIDs[1],$tagIDs[2]);
$news->save();
$news->reset();
$result = $news->has('tags2',array('title like ?','%Design%'))->find();
$test->expect(
count($result) == 1 &&
$result[0]['title'] == 'Responsive Images',
$type.': has filter on many-to-many field'
);
$result = $news->has('tags2',array('title = ?','Responsive'))->find();
$test->expect(
count($result) == 2 &&
$result[0]['title'] == 'Responsive Images' &&
$result[1]['title'] == 'CSS3 Showcase',
$type.': has filter on many-to-many field, additional test'
);
$result = $tag->has('news',array('title = ?','Responsive Images'))->find();
$test->expect(
count($result) == 2 &&
$result[0]['title'] == 'Web Design' &&
$result[1]['title'] == 'Responsive',
$type.': has filter on many-to-many field, inverse'
);
// add another tag
$news->load(array('title = ?', 'Touchable Interfaces'));
$news->tags2 = array($tagIDs[1]);
$news->save();
$news->reset();
$tag->has('news',array('text LIKE ? and title LIKE ?', '%Lorem%', '%Interface%'));
$result = $tag->find();
$test->expect(
count($result) == 1 &&
$result[0]['title'] == 'Responsive',
$type.': has filter with multiple conditions'
);
$news->has('tags2', array('title = ? OR title = ?', 'Usability', 'Web Design'));
$result = $news->afind(array('text = ?', 'Lorem Ipsun'));
$test->expect(
count($result) == 1 &&
$result[0]['title'] == 'Responsive Images',
$type.': find with condition and has filter'
);
$news->load(array('title = ?', 'Responsive Images'));
$news->author = $authorIDs[1];
$news->save();
$news->reset();
$news->has('tags2', array('title = ? OR title = ?', 'Usability', 'Web Design'));
$news->has('author', array('name = ?', 'Ridley Scott'));
$result = $news->afind();
$test->expect(
count($result) == 1 &&
$result[0]['title'] == 'Responsive Images',
$type.': find with multiple has filters on different relations'
);
// add another news to author 2
$news->load(array($news_pk.' = ?',$newsIDs[2]));
$news->author = $authorIDs[1];
$news->save();
$news->reset();
$news->has('author', array('name = ?', 'Ridley Scott'));
$news->load();
$res = array();
while (!$news->dry()) {
$res[] = $news->title;
$news->next();
}
$test->expect(
count($res) == 2 &&
$res[0] == 'Responsive Images' &&
$res[1] == 'Touchable Interfaces'
,
$type.': has filter in load context'
);
$news->reset();
$news->fields(array('title'));
$news->load();
$test->expect(
!empty($news->title) &&
empty($news->author) &&
empty($news->text) &&
empty($news->tags) &&
empty($news->tags2),
$type.': use a whitelist to restrict fields'
);
unset($news);
$news = new \NewsModel();
$news->fields(array('title','tags','tags2','author'),true);
$news->load();
$test->expect(
empty($news->title) &&
empty($news->author) &&
!empty($news->text) &&
empty($news->tags) &&
empty($news->tags2),
$type.': use a blacklist to restrict fields'
);
unset($news);
$news = new \NewsModel();
$news->fields(array('tags.title'));
$news->load();
$test->expect(
!empty($news->tags[0]->title) &&
empty($news->tags[0]->news),
$type.': set restricted fields to related mappers'
);
$news->filter('tags2',null,array('order'=>'title ASC'));
$news->load(array('title = ?','Responsive Images'));
$test->expect(
$news->tags2[0]->title == 'Responsive' &&
$news->tags2[1]->title == 'Web Design',
$type.': filter with sorting of related records'
);
// get all tags sorted by their usage in news articles
$tag->reset();
$tag->countRel('news');
$result = $tag->find(null,array('order'=>'count_news DESC, title'))->castAll(0);
$test->expect(
$result[0]['title'] == 'Responsive' &&
$result[0]['count_news'] == 3 &&
$result[1]['title'] == 'Usability' &&
$result[1]['count_news'] == 1 &&
$result[2]['title'] == 'Web Design' &&
$result[2]['count_news'] == 1,
$type.': count and sort on many-to-many relation'
);
// get all authors sorted by the amount of news they have written
$author->reset();
$author->countRel('news');
$result = $author->find(null,array('order'=>'count_news DESC'))->castAll(0);
$test->expect(
$result[0]['name'] == 'Ridley Scott' &&
$result[0]['count_news'] == 2 &&
$result[1]['name'] == 'Johnny English' &&
$result[1]['count_news'] == 1 &&
$result[2]['name'] == 'James T. Kirk' &&
$result[2]['count_news'] == null,
$type.': count and sort on one-to-many relation'
);
$tag->reset();
$tag->countRel('news');
$result = $tag->find(null,array('order'=>'count_news DESC, title DESC','limit'=>1,'offset'=>1))->castAll(0);
$test->expect(
$result[0]['title'] == 'Web Design' &&
$result[0]['count_news'] == 1,
$type.': apply limit and offset on aggregated collection'
);
$author->reset();
$author->countRel('news');
$author->has('news',array('text like ?','%Lorem%'));
$result = $author->find()->castAll(0);
$test->expect(
count($result) == 1 &&
$result[0]['name'] == 'Ridley Scott' &&
$result[0]['count_news'] == 2 ,
$type.': has-filter and 1:M relation counter'
);
$author->reset();
$id = $author->load()->next()->_id;
$tag->reset();
$tag->countRel('news');
$tag->has('news',array('author = ?',$id));
$result = $tag->find(null,array('order'=>'count_news desc'))->castAll(0);
$test->expect(
count($result) == 2 &&
$result[0]['title'] == 'Responsive' &&
$result[0]['count_news'] == 3 &&
$result[1]['title'] == 'Web Design' &&
$result[1]['count_news'] == 1,
$type.': has-filter and M:M relation counter'
);
///////////////////////////////////
return $test->results();
}
}

View File

@@ -1,335 +0,0 @@
<?php
use App\Controller;
class Test_Relation {
/**
* unify results for better comparison
*/
private function getResult($result)
{
$out = array();
foreach ($result as $row) {
if(is_object($row))
$row = $row->cast();
unset($row['_id']);
unset($row['id']);
unset($row['aid']);
unset($row['uid']);
unset($row['nid']);
unset($row['tid']);
unset($row['pid']);
unset($row['profile_id']);
foreach ($row as $col => $val) {
if (empty($val) || is_null($val))
unset($row[$col]);
}
$out[] = $row;
}
return $out;
}
function run($db,$type)
{
$test = new \Test();
// clear existing data
\AuthorModel::setdown();
\TagModel::setdown();
\NewsModel::setdown();
\ProfileModel::setdown();
// setup models
\AuthorModel::setup();
\TagModel::setup();
\NewsModel::setup();
\ProfileModel::setup();
// setup Author
///////////////////////////////////
$author_id = array();
$author = new \AuthorModel();
$ac=$author::resolveConfiguration();
$author_pk = (is_int(strpos($type,'sql'))?$ac['primary']:'_id');
$author->name = 'Johnny English';
$author->save();
$author_id[] = $author->_id;
$author->reset();
$author->name = 'Ridley Scott';
$author->save();
$author_id[] = $author->_id;
$author->reset();
$author->name = 'James T. Kirk';
$author->save();
$author_id[] = $author->_id;
$author->reset();
$allauthors = $author->find()->castAll();
$allauthors = $this->getResult($allauthors);
$test->expect(
json_encode($allauthors) ==
'[{"name":"Johnny English"},{"name":"Ridley Scott"},{"name":"James T. Kirk"}]',
$type.': all AuthorModel items created'
);
// setup Tags
///////////////////////////////////
$tag_id = array();
$tag = new \TagModel();
$tc=$tag::resolveConfiguration();
$tag_pk = (is_int(strpos($type,'sql'))?$tc['primary']:'_id');
$tag->title = 'Web Design';
$tag->save();
$tag_id[] = $tag->_id;
$tag->reset();
$tag->title = 'Responsive';
$tag->save();
$tag_id[] = $tag->_id;
$tag->reset();
$tag->title = 'Usability';
$tag->save();
$tag_id[] = $tag->_id;
$tag->reset();
$allTags = $this->getResult($tag->find());
$test->expect(
json_encode($allTags) ==
'[{"title":"Web Design"},{"title":"Responsive"},{"title":"Usability"}]',
$type.': all TagModel items created'
);
// setup News
///////////////////////////////////
$news_id = array();
$news = new \NewsModel();
$nc=$news::resolveConfiguration();
$news_pk = (is_int(strpos($type,'sql'))?$nc['primary']:'_id');
$news->title = 'Responsive Images';
$news->text = 'Lorem Ipsun';
$news->save();
$news_id[] = $news->_id;
$news->reset();
$news->title = 'CSS3 Showcase';
$news->text = 'News Text 2';
$news->save();
$news_id[] = $news->_id;
$news->reset();
$news->title = 'Touchable Interfaces';
$news->text = 'Lorem Foo';
$news->save();
$news_id[] = $news->_id;
$news->reset();
$allnews = $this->getResult($news->find());
$test->expect(
json_encode($allnews) ==
'[{"title":"Responsive Images","text":"Lorem Ipsun"},{"title":"CSS3 Showcase","text":"News Text 2"},{"title":"Touchable Interfaces","text":"Lorem Foo"}]',
$type.': all NewsModel items created'
);
// belongs-to author relation
///////////////////////////////////
$author->load();
$news->load(array($news_pk.' = ?',$news_id[0]));
$news->author = $author;
$news->save();
$news->reset();
$news->load(array($news_pk.' = ?', $news_id[0]));
$test->expect(
$news->author->name == 'Johnny English',
$type.': belongs-to-one: author relation created'
);
$news->author = NULL;
$news->save();
$news->reset();
$news->load(array($news_pk.' = ?', $news_id[0]));
$test->expect(
empty($news->author),
$type.': belongs-to-one: author relation released'
);
$news->author = $author->_id;
$news->save();
$news->reset();
$news->load(array($news_pk.' = ?', $news_id[0]));
$test->expect(
$news->author->name == 'Johnny English',
$type.': belongs-to-one: relation created by raw id'
);
// belongs-to-many tag relation
///////////////////////////////////
$tag1 = new \TagModel();
$tag1->load(array($tag_pk.' = ?', $tag_id[0]));
$tag2 = new \TagModel();
$tag2->load(array($tag_pk.' = ?', $tag_id[1]));
$news->tags = array($tag1,$tag2);
$news->save();
$news->reset();
$news->load(array($news_pk.' = ?', $news_id[0]));
$test->expect(
$news->tags[0]->title == 'Web Design' && $news->tags[1]->title == 'Responsive',
$type.': belongs-to-many: relations created with array of mapper objects'
);
$news->reset();
$news->load(array($news_pk.' = ?', $news_id[1]));
$news->tags = array($tag_id[1],$tag_id[2]);
$news->save();
$news->reset();
$news->load(array($news_pk.' = ?', $news_id[1]));
$test->expect(
$news->tags[0]->title == 'Responsive' && $news->tags[1]->title == 'Usability',
$type.': belongs-to-many: relations created with array of IDs'
);
$news->tags = null;
$news->save();
$news->reset();
$news->load(array($news_pk.' = ?', $news_id[1]));
$test->expect(
empty($news->tags),
$type.': belongs-to-many: relations released'
);
$tag->reset();
$news->load(array($news_pk.' = ?', $news_id[1]));
$news->tags = $tag->load(array($tag_pk.' != ?',$tag_id[0]));
$news->save();
$news->reset();
$news->load(array($news_pk.' = ?', $news_id[1]));
$test->expect(
$news->tags[0]->title == 'Responsive' && $news->tags[1]->title == 'Usability',
$type.': belongs-to-many: relations created with hydrated mapper'
);
$news->reset();
$tag->reset();
$news->load(array($news_pk.' = ?', $news_id[2]));
$news->tags = $tag_id[0].';'.$tag_id[2];
$news->save();
$news->reset();
$news->load(array($news_pk.' = ?', $news_id[2]));
$test->expect(
$news->tags[0]->title == 'Web Design' && $news->tags[1]->title == 'Usability',
$type.': belongs-to-many: relations created with split-able string'
);
$test->expect(
is_object($news->tags) && $news->tags instanceof \DB\CortexCollection,
$type.': belongs-to-many: result is collection'
);
// has-one relation
///////////////////////////////////
$profile = new ProfileModel();
$pc=$profile::resolveConfiguration();
$profile_pk = (is_int(strpos($type,'sql'))?$pc['primary']:'_id');
$profile->message = 'Hello World';
$profile->author = $author->load(array($author_pk.' = ?',$author_id[0]));
$profile->save();
$profile_id = $profile->_id;
$profile->reset();
$author->reset();
$author->load(array($author_pk.' = ?', $author_id[0]));
$profile->load(array($profile_pk.' = ?', $profile_id));
$test->expect(
$author->profile->message == 'Hello World' &&
$profile->author->name == "Johnny English",
$type.': has-one: relation assigned'
);
$profile->reset();
$profile->message = 'I\'m feeling lucky';
$profile->image = 'lolcat.jpg';
$author->reset();
$author->load(array($author_pk.' = ?',$author_id[1]));
$author->profile = $profile;
$author->save();
$profile->reset();
$author->reset();
$author->load(array($author_pk.' = ?', $author_id[1]));
$test->expect(
$author->profile->message == 'I\'m feeling lucky',
$type.': has-one: inverse relation'
);
// has-many relation
///////////////////////////////////
$author->load(array($author_pk.' = ?', $author_id[0]));
$result = $this->getResult($author->news);
$test->expect(
$result[0]['title'] == "Responsive Images" &&
$result[0]['tags'][0]['title'] == 'Web Design' &&
$result[0]['tags'][1]['title'] == 'Responsive',
$type.': has-many inverse relation'
);
// many to many relation
///////////////////////////////////
$news->load(array($news_pk.' = ?',$news_id[0]));
$news->tags2 = array($tag_id[0],$tag_id[1]);
$news->save();
$news->reset();
$news->load(array($news_pk.' = ?',$news_id[0]));
$test->expect(
$news->tags2[0]['title'] == 'Web Design' &&
$news->tags2[1]['title'] == 'Responsive',
$type.': many-to-many relation created'
);
$test->expect(
is_object($news->tags2) && $news->tags2 instanceof \DB\CortexCollection,
$type.': many-to-many: result is collection'
);
$news->load(array($news_pk.' = ?', $news_id[0]));
$news->tags2 = NULL;
$news->save();
$news->reset();
$news->load(array($news_pk.' = ?', $news_id[0]));
$test->expect(
is_null($news->tags2),
$type.': many-to-many relation released'
);
$all = $news->find();
$test->expect(
$all[1]->tags2 === NULL
&& $all[2]->author === NULL,
$type.': empty relations are NULL'
);
$arr = $news->cast();
$test->expect(
is_array($arr['tags']),
$type.': collection becomes array in casted model'
);
if ($type == 'mongo') {
$test->expect(
is_string($arr['_id']),
$type.': id becomes string in casted model'
);
}
///////////////////////////////////
return $test->results();
}
}

View File

@@ -1,364 +0,0 @@
<?php
use App\Controller;
class Test_Syntax {
function run($db,$type)
{
$test = new \Test();
$tname = 'test_cortex';
\DB\Cortex::setdown($db, $tname);
$fields = array(
'title' => array('type' => \DB\SQL\Schema::DT_TEXT),
'num1' => array('type' => \DB\SQL\Schema::DT_INT4),
'num2' => array('type' => \DB\SQL\Schema::DT_INT4),
);
\DB\Cortex::setup($db, $tname, $fields);
// adding some testing data
$cx = new \DB\Cortex($db, $tname);
$cx->title = 'bar1';
$cx->save();
$cx->reset();
$cx->title = 'baz2';
$cx->num1 = 1;
$cx->save();
$cx->reset();
$cx->title = 'foo3';
$cx->num1 = 4;
$cx->save();
$cx->reset();
$cx->title = 'foo4';
$cx->num1 = 3;
$cx->save();
$cx->reset();
$cx->title = 'foo5';
$cx->num1 = 3;
$cx->num2 = 5;
$cx->save();
$cx->reset();
$cx->title = 'foo6';
$cx->num1 = 3;
$cx->num2 = 1;
$cx->save();
$cx->reset();
$cx->title = 'foo7';
$cx->num1 = 3;
$cx->num2 = 10;
$cx->save();
$cx->reset();
$cx->title = 'foo8';
$cx->num1 = 5;
$cx->save();
$cx->reset();
$cx->title = 'foo9';
$cx->num1 = 8;
$cx->save();
$cx->reset();
$result = $this->getResult($cx->find());
$expected = array(
0 => array(
'title' => 'bar1',
),
1 => array(
'num1' => 1,
'title' => 'baz2',
),
2 => array(
'num1' => 4,
'title' => 'foo3',
),
3 => array(
'num1' => 3,
'title' => 'foo4',
),
4 => array(
'num1' => 3,
'num2' => 5,
'title' => 'foo5',
),
5 => array(
'num1' => 3,
'num2' => 1,
'title' => 'foo6',
),
6 => array(
'num1' => 3,
'num2' => 10,
'title' => 'foo7',
),
7 => array(
'num1' => 5,
'title' => 'foo8',
),
8 => array(
'num1' => 8,
'title' => 'foo9',
),
);
$test->expect(
json_encode($result) == json_encode($expected),
$type.': init mapper, adding records'
);
// operator =
$result = $this->getResult($cx->find(array('title = ?', 'foo7')));
$expected = array(
0 => array(
'num1' => 3,
'num2' => 10,
'title' => 'foo7',
),
);
$test->expect(
json_encode($result) == json_encode($expected),
$type.': operator check: ='
);
// operator >
$result = $this->getResult($cx->find(array('num1 > ?', 4)));
$expected = array(
0 => array(
'num1' => 5,
'title' => 'foo8',
),
1 => array(
'num1' => 8,
'title' => 'foo9',
),
);
$test->expect(
json_encode($result) == json_encode($expected),
$type.': operator check: >'
);
// operator >=
$result = $this->getResult($cx->find(array('num1 >= ?', 5)));
$test->expect(
json_encode($result) == json_encode($expected),
$type.': operator check: >='
);
// operator <
$result = $this->getResult($cx->find(array('num2 < ?', 2)));
$expected = array(
0 => array(
'num1' => 3,
'num2' => 1,
'title' => 'foo6',
),
);
$test->expect(
json_encode($result) == json_encode($expected),
$type.': operator check: <'
);
// operator <=
$result = $this->getResult($cx->find(array('num2 <= ?', 1)));
$test->expect(
json_encode($result) == json_encode($expected),
$type.': operator check: <='
);
// operator without binding
$result = $this->getResult($cx->find(array('num1 > 4')));
$expected = array(
0 => array(
'num1' => 5,
'title' => 'foo8',
),
1 => array(
'num1' => 8,
'title' => 'foo9',
),
);
$test->expect(
json_encode($result) == json_encode($expected),
$type.': operator without binding'
);
// field comparision
$result = $this->getResult($cx->find(
array('num2 > num1', 1)));
$expected = array(
0 => array(
'num1' => 3,
'num2' => 5,
'title' => 'foo5',
),
1 => array(
'num1' => 3,
'num2' => 10,
'title' => 'foo7',
),
);
$test->expect(
json_encode($result) == json_encode($expected),
$type.': check field comparision'
);
// lookahead search
$result = $this->getResult($cx->find(array('title like ?', '%o6')));
$expected = array(
0 => array(
'num1' => 3,
'num2' => 1,
'title' => 'foo6',
),
);
$test->expect(
json_encode($result) == json_encode($expected),
$type.': lookahead search'
);
// lookbehind search
$result = $this->getResult($cx->find(array('title like ?', 'bar%')));
$expected = array(
0 => array(
'title' => 'bar1',
),
);
$test->expect(
json_encode($result) == json_encode($expected),
$type.': lookbehind search'
);
// full search
$result = $this->getResult($cx->find(array('title like ?', '%a%')));
$expected = array(
0 => array(
'title' => 'bar1',
),
1 => array(
'num1' => 1,
'title' => 'baz2',
),
);
$test->expect(
json_encode($result) == json_encode($expected),
$type.': full search'
);
// negated search
$result = $this->getResult($cx->find(array('title not like ?', 'foo%')));
$test->expect(
json_encode($result) == json_encode($expected),
$type.': negated search'
);
// AND / OR chaining
$result = $this->getResult($cx->find(
array('(num2 < ? AND num1 > ?) OR title like ?', 2, 1, '%o9')));
$expected = array(
0 => array(
'num1' => 3,
'num2' => 1,
'title' => 'foo6',
),
1 => array(
'num1' => 8,
'title' => 'foo9',
),
);
$test->expect(
json_encode($result) == json_encode($expected),
$type.': check logical operator chaining'
);
// check limit
$result = $this->getResult($cx->find(
null, array('limit' => '2')));
$expected = array(
0 => array(
'title' => 'bar1',
),
1 => array(
'num1' => 1,
'title' => 'baz2',
),
);
$test->expect(
json_encode($result) == json_encode($expected),
$type.': check limit'
);
// check order
$result = $this->getResult($cx->find(
array('num2 >= ?', 1), array('order' => 'num2 desc')));
$expected = array(
0 => array(
'num1' => 3,
'num2' => 10,
'title' => 'foo7',
),
1 => array(
'num1' => 3,
'num2' => 5,
'title' => 'foo5',
),
2 => array(
'num1' => 3,
'num2' => 1,
'title' => 'foo6',
),
);
$test->expect(
json_encode($result) == json_encode($expected),
$type.': check order'
);
// IN search
$rc = $cx->find(array('num1 IN ?',array(4,5,8)));
$result = $rc->getAll('title');
sort($result);
$test->expect(
json_encode($result) == json_encode(array('foo3','foo8','foo9')),
$type.': IN operator'
);
$rc = $cx->find(array('num1 IN ? && num2 > ? && num2 NOT IN ?',array(3,4),1,array(10)));
$result = $rc->getAll('title');
$test->expect(
json_encode($result) == json_encode(array('foo5')),
$type.': enhanced IN, NOT IN operator'
);
///////////////////////////////////
return $test->results();
}
/**
* unify results for better comparison
*/
private function getResult($result)
{
$out = array();
foreach ($result as $row) {
$row = $row->cast();
unset($row['_id']);
unset($row['id']);
ksort($row);
foreach ($row as $col => $val) {
if (empty($val) || is_null($val))
unset($row[$col]);
}
$out[] = $row;
}
return $out;
}
}

View File

@@ -1,668 +0,0 @@
<?php
namespace App;
class Schema extends Controller
{
private
$roundTime = 0,
$current_test = 1,
$current_engine,
$f3,
$test,
$tname;
private function getTime()
{
$time = microtime(TRUE) - $this->f3->get('timer') - $this->roundTime;
$this->roundTime = microtime(TRUE) - $this->f3->get('timer');
return ' [ '.sprintf('%.3f', $time).'s ]';
}
private function getTestDesc($text)
{
return $this->getTime().' '.$this->current_engine.': #'.$this->current_test++.' - '.$text;
}
function get()
{
$this->f3 = \Base::instance();
$this->test = new \Test;
$this->f3->set('QUIET', false);
$this->f3->set('CACHE', false);
$dbs = array(
'mysql' => new \DB\SQL(
'mysql:host=localhost;port=3306;dbname=fatfree', 'fatfree', ''
),
'sqlite' => new \DB\SQL(
'sqlite::memory:'
// 'sqlite:db/sqlite.db'
),
'pgsql' => new \DB\SQL(
'pgsql:host=localhost;dbname=fatfree', 'fatfree', 'fatfree'
),
// 'sqlsrv2012' => new \DB\SQL(
// 'sqlsrv:SERVER=LOCALHOST\SQLEXPRESS2012;Database=fatfree','fatfree', 'fatfree'
// ),
// 'sqlsrv2008' => new \DB\SQL(
// 'sqlsrv:SERVER=LOCALHOST\SQLEXPRESS2008;Database=fatfree','fatfree', 'fatfree'
// )
);
$this->roundTime = microtime(TRUE) - \Base::instance()->get('timer');
$this->tname = 'test_table';
foreach ($dbs as $type => $db) {
$this->current_engine = $type;
$this->runTestSuite($db);
$this->current_test = 1;
}
$this->f3->set('results', $this->test->results());
}
private function runTestSuite($db)
{
$schema = new \DB\SQL\Schema($db);
$schema->dropTable($this->tname);
// create table
$table = $schema->createTable($this->tname);
$table = $table->build();
$result = $schema->getTables();
$this->test->expect(
in_array($this->tname, $result),
$this->getTestDesc('create default table')
);
unset($result);
$this->test->expect(
$table instanceof \DB\SQL\TableModifier,
$this->getTestDesc('$table->build() returns TableModifier')
);
// drop table
$table->drop();
$this->test->expect(
in_array($this->tname, $schema->getTables()) == false,
$this->getTestDesc('drop table')
);
unset($table);
// create table with columns
$table = $schema->createTable($this->tname);
$table->addColumn('title')->type($schema::DT_VARCHAR128);
$table->addColumn('number')->type($schema::DT_INT4);
$table = $table->build();
$r1 = $schema->getTables();
$r2 = $table->getCols();
$this->test->expect(
in_array($this->tname, $r1) && in_array('id', $r2)
&& in_array('title', $r2) && in_array('number', $r2),
$this->getTestDesc('create new table with additional columns')
);
unset($r1,$r2);
// testing all datatypes
foreach (array_keys($schema->dataTypes) as $index => $field) {
// testing column type
$table->addColumn('column_'.$index)->type($field);
$table->build();
$r1 = $table->getCols();
$this->test->expect(
in_array('column_'.$index, $r1),
$this->getTestDesc('adding column ['.$field.'], nullable')
);
}
$r1 = $table->getCols(true);
foreach (array_keys($schema->dataTypes) as $index => $field) {
if (isset($r1['column_'.$index])) {
$datType=$schema->findQuery($schema->dataTypes[$field]);
$compatible = $schema->isCompatible($field,$r1['column_'.$index]['type']);
$this->test->expect(
$compatible,
$this->getTestDesc('reverse lookup compatible: '.
($compatible?'YES':'NO').
', '.$field.': ['.$datType.' > '.$r1['column_'.$index]['type'].']')
);
}
}
unset($r1);
// adding some testing data
$mapper = new \DB\SQL\Mapper($db, $this->tname);
$mapper->column_5 = 123.456;
$mapper->column_6 = 123456.789012;
$mapper->column_7 = 'hello world';
$mapper->save();
$mapper->reset();
$result = $mapper->findone(array('column_7 = ?', 'hello world'))->cast();
unset($mapper);
$this->test->expect(
$result['column_7'] == 'hello world',
$this->getTestDesc('mapping dummy data')
);
$this->test->expect(
$result['column_5'] == 123.456,
$this->getTestDesc('testing float value: '.$result['column_5'])
);
$this->test->expect(
$result['column_6'] == 123456.789012,
$this->getTestDesc('testing decimal value: '.$result['column_6'])
);
$mapper = new \DB\SQL\Mapper($db, $this->tname);
$mapper->load();
$num = $this->current_engine == 'sqlite' ? '123456789.012345' : '123456789012.345678';
$mapper->column_6 = $num;
$mapper->save();
$mapper->reset();
$result = $mapper->findone(array('column_7 = ?', 'hello world'))->cast();
$this->test->expect(
$result['column_6'] == $num,
$this->getTestDesc('testing max decimal precision: '.$result['column_6'])
);
unset($mapper);
// default value text, not nullable
$table->addColumn('text_default_not_null')
->type($schema::DT_VARCHAR128)
->nullable(false)->defaults('foo bar');
$table->build();
$r1 = $table->getCols(true);
$this->test->expect(
in_array('text_default_not_null', array_keys($r1)) &&
$r1['text_default_not_null']['default'] == 'foo bar' &&
$r1['text_default_not_null']['nullable'] == false,
$this->getTestDesc('adding column [VARCHAR128], not nullable with default value')
);
unset($r1);
// some testing dummy data
$mapper = new \DB\SQL\Mapper($db, $this->tname);
$mapper->column_7 = 'tanduay';
$mapper->save();
$mapper->reset();
$result = $mapper->findone(array('column_7 = ?','tanduay'))->cast();
$this->test->expect(
$result['column_7'] == 'tanduay' &&
$result['text_default_not_null'] == 'foo bar',
$this->getTestDesc('mapping dummy data')
);
unset($mapper,$result);
// default value numeric, not nullable
$table->addColumn('int_default_not_null')
->type($schema::DT_INT4)->nullable(false)->defaults(123);
$table->build();
$r1 = $table->getCols(true);
$this->test->expect(
in_array('int_default_not_null', array_keys($r1)) &&
$r1['int_default_not_null']['default'] == 123 &&
$r1['int_default_not_null']['nullable'] == false,
$this->getTestDesc('adding column [INT4], not nullable with default value')
);
unset($r1);
// adding testing data
$mapper = new \DB\SQL\Mapper($db, $this->tname);
$mapper->column_7 = 'test3';
$mapper->save();
$mapper->reset();
$r1 = $mapper->findone(array('column_7 = ?','test3'))->cast();
$this->test->expect(
$r1['column_7'] == 'test3' &&
$r1['int_default_not_null'] == 123,
$this->getTestDesc('mapping dummy data')
);
unset($mapper,$r1);
// default value text, nullable
$table->addColumn('text_default_nullable')
->type($schema::DT_VARCHAR128)
->defaults('foo bar');
$table->build();
$r1 = $table->getCols(true);
$this->test->expect(
in_array('text_default_nullable', array_keys($r1)) &&
$r1['text_default_nullable']['default'] == 'foo bar',
$this->getTestDesc('adding column [VARCHAR128], nullable with default value')
);
unset($r1);
// adding some dummy data
$mapper = new \DB\SQL\Mapper($db, $this->tname);
$mapper->column_7 = 'test4';
$mapper->save();
$mapper->reset();
$mapper->column_7 = 'test5';
$mapper->text_default_nullable = null;
$mapper->save();
$mapper->reset();
$result = $mapper->find(array('column_7 = ? OR column_7 = ?','test4','test5'));
foreach ($result as &$r)
$r = $r->cast();
$this->test->expect(
array_key_exists(0, $result) && array_key_exists(1, $result) &&
$result[0]['column_7'] == 'test4' && $result[0]['text_default_nullable'] == 'foo bar' &&
$result[1]['column_7'] == 'test5' && $result[1]['text_default_nullable'] === null,
$this->getTestDesc('mapping dummy data')
);
unset($mapper, $result);
// default value numeric, nullable
$table->addColumn('int_default_nullable')->type($schema::DT_INT4)->defaults(123);
$table->build();
$r1 = $table->getCols(true);
$this->test->expect(
in_array('int_default_nullable', array_keys($r1)) == true &&
$r1['int_default_nullable']['default'] == 123,
$this->getTestDesc('adding column [INT4], nullable with default value')
);
unset($r1);
// adding dummy data
$mapper = new \DB\SQL\Mapper($db, $this->tname);
$mapper->column_7 = 'test6';
$mapper->save();
$mapper->reset();
$mapper->column_7 = 'test7';
$mapper->int_default_nullable = null;
$mapper->save();
$mapper->reset();
$result = $mapper->find(array('column_7 = ? OR column_7 = ?', 'test6', 'test7'));
foreach ($result as &$r)
$r = $r->cast();
$this->test->expect(
array_key_exists(0, $result) && array_key_exists(1, $result) &&
$result[0]['column_7'] == 'test6' && $result[0]['int_default_nullable'] === 123 &&
$result[1]['column_7'] == 'test7' && $result[1]['int_default_nullable'] === null,
$this->getTestDesc('mapping dummy data')
);
unset($mapper, $result);
// current timestamp
$table->addColumn('stamp')
->type($schema::DT_TIMESTAMP)
->nullable(false)
->defaults($schema::DF_CURRENT_TIMESTAMP);
$table->build();
$r1 = $table->getCols(true);
$this->test->expect(
in_array('stamp', array_keys($r1)) &&
$r1['stamp']['default'] == $schema::DF_CURRENT_TIMESTAMP,
$this->getTestDesc(
'adding column [TIMESTAMP], not nullable with current_timestamp default value')
);
unset($r1);
// datetime nullable
$table->addColumn('datetime')->type_datetime()->nullable(true);
$table->build();
$r1 = $table->getCols(true);
$this->test->expect(
in_array('datetime', array_keys($r1)) &&
$r1['datetime']['nullable'] == true,
$this->getTestDesc(
'adding column [DATETIME], nullable, no default')
);
unset($r1);
// adding dummy data
$mapper = new \DB\SQL\Mapper($db, $this->tname);
$mapper->column_7 = 'test_datetime';
$mapper->datetime = NULL;
$mapper->save();
$mapper->reset();
$result = $mapper->find(array('column_7 = ?', 'test_datetime'));
foreach ($result as &$r)
$r = $r->cast();
$this->test->expect(
array_key_exists(0, $result) && $result[0]['column_7'] == 'test_datetime' &&
$result[0]['datetime'] === null,
$this->getTestDesc('mapping dummy data')
);
unset($mapper, $result);
// rename column
$table->renameColumn('text_default_not_null', 'title123');
$table->build();
$r1 = $table->getCols();
$this->test->expect(
in_array('title123', $r1) && !in_array('text_default_not_null', $r1),
$this->getTestDesc('renaming column')
);
unset($r1);
// adding dummy data
$mapper = new \DB\SQL\Mapper($db, $this->tname);
$mapper->title123 = 'test8';
$mapper->save();
$mapper->reset();
$result = $mapper->findone(array('title123 = ?','test8'));
$this->test->expect(
!$result->dry(),
$this->getTestDesc('mapping dummy data')
);
$table->renameColumn('title123', 'text_default_not_null');
$table->build();
unset($result,$mapper);
// remove column
$table->dropColumn('column_1');
$table->build();
$r1 = $table->getCols();
$this->test->expect(
!in_array('column_1', $r1),
$this->getTestDesc('removing column')
);
unset($r1);
// rename table
$schema->dropTable('test123');
$table->rename('test123');
$result = $schema->getTables();
$this->test->expect(
in_array('test123', $result) && !in_array($this->tname, $result),
$this->getTestDesc('renaming table')
);
$table->rename($this->tname);
unset($result);
// check record count
$mapper = new \DB\SQL\Mapper($db, $this->tname);
$this->test->expect(
count($mapper->find()) == 9,
$this->getTestDesc('check record count')
);
unset($mapper);
// adding composite primary keys
$table->addColumn('version')->type($schema::DT_INT4)->nullable(false)->defaults(1);
$table->primary(array('id', 'version'));
$table->build();
$r1 = $table->getCols(true);
$this->test->expect(!empty($r1) && isset($r1['version']) &&
$r1['id']['pkey'] == true && $r1['version']['pkey'] == true,
$this->getTestDesc('adding composite primary-keys')
);
unset($r1);
// check record count
$mapper = new \DB\SQL\Mapper($db, $this->tname);
$this->test->expect(
count($mapper->find()) == 9,
$this->getTestDesc('check record count')
);
unset($mapper);
// drop table
$schema->dropTable($this->tname);
$this->test->expect(
!in_array($this->tname, $schema->getTables()),
$this->getTestDesc('drop table')
);
// adding composite primary keys
$table = $schema->createTable($this->tname);
$table->addColumn('version')->type($schema::DT_INT4)
->defaults(1)->nullable(false);
$table->primary(array('id', 'version'));
$table = $table->build();
$r1 = $table->getCols(true);
$this->test->expect(!empty($r1) &&
$r1['id']['pkey'] == true && $r1['version']['pkey'] == true,
$this->getTestDesc('creating new table with composite key')
);
$this->test->expect(!empty($r1) &&
$r1['version']['default'] == '1',
$this->getTestDesc('default value on composite primary key')
);
unset($r1);
// more fields to composite primary key table
$table->addColumn('title')->type($schema::DT_VARCHAR256);
$table->addColumn('title2')->type($schema::DT_TEXT);
$table->addColumn('title_notnull')
->type($schema::DT_VARCHAR128)->nullable(false)->defaults("foo");
$table->build();
$r1 = $table->getCols(true);
$this->test->expect(
array_key_exists('title', $r1) &&
array_key_exists('title_notnull', $r1) &&
$r1['id']['pkey'] == true && $r1['version']['pkey'] == true,
$this->getTestDesc('adding more fields to composite pk table')
);
unset($r1);
// testing primary keys with inserted data
$mapper = new \DB\SQL\Mapper($db, $this->tname);
$mapper->title = 'test1';
$mapper->save();
$mapper->reset();
$mapper->id = 1;
$mapper->title = 'nullable';
$mapper->version = 2;
$mapper->save();
$mapper->reset();
$mapper->title = 'test3';
$mapper->title2 = 'foobar';
$mapper->title_notnull = 'bar';
$mapper->save();
$result = array_map(array($mapper,'cast'),$mapper->find());
$cpk_expected = array(
0=>array(
'id' => 1,
'version' => 1,
'title' => 'test1',
'title2' => NULL,
'title_notnull' => 'foo',
),
1=>array(
'id' => 1,
'version' => 2,
'title' => 'nullable',
'title2' => NULL,
'title_notnull' => 'foo',
),
2=>array(
'id' => 2,
'version' => 1,
'title' => 'test3',
'title2' => 'foobar',
'title_notnull' => 'bar',
),
);
foreach ($result as &$r)
ksort($r);
foreach ($cpk_expected as &$r)
ksort($r);
$this->test->expect(
json_encode($result) == json_encode($cpk_expected),
$this->getTestDesc('adding items with composite primary-keys')
);
$mapper = new \DB\SQL\Mapper($db, $this->tname);
$mapper->load();
$rec_count_cur = $mapper->loaded();
$schema->truncateTable($this->tname);
$mapper->reset();
$mapper->load();
$rec_count_new = $mapper->loaded();
$this->test->expect(
$rec_count_cur==3 && $rec_count_new == 0,
$this->getTestDesc('truncate table')
);
$schema->dropTable($this->tname);
// indexes
$table = $schema->createTable($this->tname);
$table->addColumn('rawtest', array('type' => $schema::DT_VARCHAR256, 'default' => 'foo'));
$table->addColumn('text')->type($schema::DT_TEXT);
$table->addColumn('foo')->type($schema::DT_VARCHAR128)->index();
$table = $table->build();
$r1 = $table->getCols(true);
$this->test->expect(
isset($r1['rawtest']) && $r1['rawtest']['default'] = 'foo',
$this->getTestDesc('adding column with options array')
);
$indexes = $table->listIndex();
$this->test->expect(
isset($indexes[$table->name.'___foo']),
$this->getTestDesc('column index on table creation')
);
$table->addColumn('bar')->type($schema::DT_VARCHAR128)->index(true);
$table->addColumn('baz')->type($schema::DT_VARCHAR128);
$table->addIndex(array('foo', 'baz'));
$table->build();
$indexes = $table->listIndex();
$this->test->expect(
isset($indexes[$table->name.'___bar']),
$this->getTestDesc('column index on table alteration')
);
$this->test->expect(
isset($indexes[$table->name.'___bar']) && $indexes[$table->name.'___bar']['unique'] == true,
$this->getTestDesc('unique index')
);
$this->test->expect(
isset($indexes[$table->name.'___foo__baz']),
$this->getTestDesc('index on combined columns')
);
if($this->current_engine == 'sqlite') {
$table->dropColumn('rawtest');
$table->build();
$indexes = $table->listIndex();
$this->test->expect(
isset($indexes[$table->name.'___foo__baz']) && isset($indexes[$table->name.'___bar'])
&& $indexes[$table->name.'___bar']['unique'],
$this->getTestDesc('preserve indexes after table rebuild')
);
}
$table->dropIndex($table->name.'___bar');
$table->build();
$indexes = $table->listIndex();
$this->test->expect(
!array_key_exists($table->name.'___bar',$indexes),
$this->getTestDesc('drop index')
);
// update column
$table->updateColumn('bar',$schema::DT_TEXT);
$table->build();
$r1 = $table->getCols(true);
$text = preg_match('/sybase|dblib|odbc|sqlsrv/',$this->current_engine)
? 'nvarchar' : 'text';
$this->test->expect(
array_key_exists('bar', $r1) && $r1['bar']['type'] == $text,
$this->getTestDesc('update column')
);
// update column
$cols = $table->getCols(true);
$bar = $cols['bar'];
$col = new \DB\SQL\Column('bar',$table);
$col->copyfrom($bar);
$col->type_varchar(60);
$col->defaults('great');
$table->updateColumn('bar',$col);
$table->build();
$r1 = $table->getCols(true);
$this->test->expect(
array_key_exists('bar', $r1)
&& $r1['bar']['default'] == 'great',
$this->getTestDesc('update column and default')
);
// update column default only
$cols = $table->getCols(true);
$bar = $cols['bar'];
$col = new \DB\SQL\Column('bar',$table);
$col->copyfrom($bar);
$col->passThrough();
$col->defaults('');
$table->updateColumn('bar',$col);
$table->build();
$r1 = $table->getCols(true);
$this->test->expect(
array_key_exists('bar', $r1) && $r1['bar']['default'] == '',
$this->getTestDesc('update default value')
);
$col->nullable(false);
$table->updateColumn('bar',$col);
$table->build();
$r1 = $table->getCols(true);
$this->test->expect(
array_key_exists('bar', $r1) && $r1['bar']['nullable'] == false,
$this->getTestDesc('update nullable flag')
);
// create table with text not nullable column
$table2 = $schema->createTable($this->tname.'_notnulltext');
$table2->addColumn('desc')->type($schema::DT_TEXT)->nullable(false);
$table2 = $table2->build();
$r1 = $schema->getTables();
$r2 = $table2->getCols(true);
$this->test->expect(
in_array($this->tname.'_notnulltext', $r1) && array_key_exists('desc', $r2)
&& $r2['desc']['nullable']==false,
$this->getTestDesc('create new table with not nullable text column')
);
$table2->drop();
// boolean fields are actually bit/tinyint
$schema->dropTable($this->tname.'_notnullbool');
$table2 = $schema->createTable($this->tname.'_notnullbool');
$table2->addColumn('active')->type($schema::DT_BOOL)->nullable(false);
$table2 = $table2->build();
$r1 = $schema->getTables();
$r2 = $table2->getCols(true);
$this->test->expect(
in_array($this->tname.'_notnullbool', $r1) && array_key_exists('active', $r2)
&& $r2['active']['nullable']==false,
$this->getTestDesc('create new table with not nullable boolean column')
);
$table2->addColumn('active2')->type($schema::DT_BOOL)->nullable(false)->defaults(0);
$table2->addColumn('active3')->type($schema::DT_BOOL)->nullable(false)->defaults(1);
$table2->build();
$r1 = $schema->getTables();
$r2 = $table2->getCols(true);
$this->test->expect(
in_array($this->tname.'_notnullbool', $r1)
&& array_key_exists('active2', $r2) && $r2['active2']['nullable']==false &&
((int)$r2['active2']['default']==0||$r2['active2']['default']=='false')
&& array_key_exists('active3', $r2) && $r2['active3']['nullable']==false &&
((int)$r2['active3']['default']==1||$r2['active3']['default']=='true'),
$this->getTestDesc('add not nullable boolean columns with default to existing table')
);
$table2->drop();
}
}

View File

@@ -463,11 +463,20 @@ class System extends Controller\AccessController {
$map->getById($mapId);
if($map->hasAccess($activeCharacter)){
$newSystemModel = Model\BasicModel::getNew('SystemModel');
foreach($systemIds as $systemId){
if( $system = $map->getSystemById($systemId) ){
// check whether system should be deleted OR set "inactive"
if( $this->checkDeleteMode($map, $system) ){
$system->erase();
// delete log
// -> first set updatedCharacterId -> required for activity log
$system->updatedCharacterId = $activeCharacter;
$system->update();
// ... now get fresh object and delete..
$newSystemModel->getById( $system->id, 0);
$newSystemModel->erase();
$newSystemModel->reset();
}else{
// keep data -> set "inactive"
$system->setActive(false);