$connManager = ConnectionManager::getInstance(); $conn = $connManager->create( '{{id}}', '' ); $conn = $connManager->default(); // return PDO connection object $result = $conn->query( ); $stm = $conn->prepare( ); $stm->execute( ); foreach( $connManager as $dataSourceId => $dataSourceConfig ) { }
Inheritance: implements ArrayAcces\ArrayAccess
 public function testGetTables()
 {
     $manager = ConnectionManager::getInstance();
     $conn = $manager->getConnection('mysql');
     $driver = $manager->getQueryDriver('mysql');
     $conn->query("DROP TABLE IF EXISTS t1");
     $conn->query("CREATE TABLE t1 (val enum('a','b','c') );");
     $parser = new MysqlTableParser($driver, $conn);
     $tables = $parser->getTables();
     $this->assertNotEmpty($tables);
     $schema = $parser->reverseTableSchema('t1');
     $this->assertNotNull($schema);
     /*
             $sql = $parser->getTableSql('foo');
             ok($sql);
     
             $columns = $parser->parseTableSql('foo');
             $this->assertNotEmpty($columns);
     
             $columns = $parser->parseTableSql('bar');
             $this->assertNotEmpty($columns);
     
             $schema = $parser->reverseTableSchema('bar');
             $this->assertNotNull($schema);
     
             $id = $schema->getColumn('id');
             $this->assertNotNull($id);
             $this->assertTrue($id->autoIncrement);
             $this->assertEquals('INTEGER',$id->type);
             $this->assertEquals('int',$id->isa);
             $this->assertTrue($id->primary);
     */
 }
Example #2
0
 public function execute()
 {
     $options = $this->options;
     $logger = $this->logger;
     $id = $this->getCurrentDataSourceId();
     $logger->debug("Finding schema classes...");
     $schemas = $this->findSchemasByArguments(func_get_args());
     $logger->debug("Initialize schema builder...");
     $connectionManager = ConnectionManager::getInstance();
     $conn = $connectionManager->getConnection($id);
     $driver = $connectionManager->getQueryDriver($id);
     $sqlBuilder = SqlBuilder::create($driver, array('rebuild' => $options->rebuild, 'clean' => $options->clean));
     $builder = new DatabaseBuilder($conn, $sqlBuilder, $this->logger);
     $sqls = $builder->build($schemas);
     $sqlOutput = join("\n", $sqls);
     if ($file = $this->options->file) {
         $fp = fopen($file, 'w');
         fwrite($fp, $sqlOutput);
         fclose($fp);
     }
     if ($this->options->basedata) {
         $collection = new SchemaCollection($schemas);
         $collection = $collection->evaluate();
         $seedBuilder = new SeedBuilder($this->getConfigLoader(), $this->logger);
         $seedBuilder->build($collection);
     }
     $time = time();
     $logger->info("Setting migration timestamp to {$time}");
     $metadata = new Metadata($driver, $conn);
     // update migration timestamp
     $metadata['migration'] = $time;
     $logger->info($logger->formatter->format('Done. ' . count($schemas) . " schema tables were generated into data source '{$id}'.", 'green'));
 }
Example #3
0
 public static function createWithDataSource($dsId)
 {
     $connm = ConnectionManager::getInstance();
     $connection = $connm->getConnection($dsId);
     $driver = $connm->getQueryDriver($dsId);
     return new self($driver, $connection);
 }
Example #4
0
 public function __construct($dsIds)
 {
     $c = ServiceContainer::getInstance();
     $this->logger = $c['logger'];
     $this->connectionManager = ConnectionManager::getInstance();
     // XXX: get data source id list from config loader
     $this->dataSourceIds = (array) $dsIds;
 }
Example #5
0
 public function execute()
 {
     $options = $this->options;
     $logger = $this->logger;
     $configLoader = $this->getConfigLoader(true);
     $id = $this->getCurrentDataSourceId();
     $logger->debug('Finding schema classes...');
     $schemas = SchemaUtils::findSchemasByArguments($configLoader, func_get_args(), $this->logger);
     $logger->debug('Initialize schema builder...');
     if ($output = $this->options->output) {
         $dataSourceConfig = $configLoader->getDataSource($id);
         $driverType = $dataSourceConfig['driver'];
         switch ($driverType) {
             case 'sqlite':
                 $driver = new SQLiteDriver();
                 break;
             case 'mysql':
                 $driver = new MySQLDriver();
                 break;
             case 'pgsql':
                 $driver = new PgSQLDriver();
                 break;
             default:
                 throw new Exception("Unsupported driver type: {$driverType}");
                 break;
         }
         $sqlBuilder = SqlBuilder::create($driver, ['rebuild' => $options->rebuild, 'clean' => $options->clean]);
         $fp = fopen($output, 'w');
         foreach ($schemas as $schema) {
             $sqls = $sqlBuilder->buildTable($schema);
             fwrite($fp, implode("\n", $sqls));
             $sqls = $sqlBuilder->buildIndex($schema);
             fwrite($fp, implode("\n", $sqls));
             $sqls = $sqlBuilder->buildForeignKeys($schema);
             fwrite($fp, implode("\n", $sqls));
         }
         fclose($fp);
         $this->logger->warn('Warning: seeding is not supported when using --output option.');
     } else {
         $connectionManager = ConnectionManager::getInstance();
         $conn = $connectionManager->getConnection($id);
         $driver = $connectionManager->getQueryDriver($id);
         $sqlBuilder = SqlBuilder::create($driver, ['rebuild' => $options->rebuild, 'clean' => $options->clean]);
         $bootstrap = new Bootstrap($conn, $sqlBuilder, $this->logger);
         $bootstrap->build($schemas);
         if ($this->options->basedata) {
             $bootstrap->seed($schemas, $configLoader);
         }
         $time = time();
         $logger->info("Setting migration timestamp to {$time}");
         $metadata = new Metadata($conn, $driver);
         // update migration timestamp
         $metadata['migration'] = $time;
         $logger->info($logger->formatter->format('Done. ' . count($schemas) . " schema tables were generated into data source '{$id}'.", 'green'));
     }
 }
Example #6
0
 public function execute()
 {
     // support for schema file or schema class names
     $options = $this->options;
     $logger = $this->logger;
     $dataSource = $this->getCurrentDataSourceId();
     $connectionManager = \LazyRecord\ConnectionManager::getInstance();
     $this->createDB($connectionManager->getDataSource($dataSource));
     $this->logger->info('Done');
 }
Example #7
0
 public function setUp()
 {
     $annnotations = $this->getAnnotations();
     $configLoader = ConfigLoader::getInstance();
     $configLoader->loadFromSymbol(true);
     $configLoader->setDefaultDataSourceId($this->getDriverType());
     $connManager = ConnectionManager::getInstance();
     $connManager->init($configLoader);
     try {
         $dbh = $connManager->getConnection($this->getDriverType());
     } catch (PDOException $e) {
         if ($this->allowConnectionFailure) {
             $this->markTestSkipped(sprintf("Can not connect to database by data source '%s' message:'%s' config:'%s'", $this->getDriverType(), $e->getMessage(), var_export($configLoader->getDataSource($this->getDriverType()), true)));
             return;
         } else {
             echo sprintf("Can not connect to database by data source '%s' message:'%s' config:'%s'", $this->getDriverType(), $e->getMessage(), var_export($configLoader->getDataSource($this->getDriverType()), true));
             throw $e;
         }
     }
     $driver = $connManager->getQueryDriver($this->getDriverType());
     $this->assertInstanceOf('SQLBuilder\\Driver\\BaseDriver', $driver, 'QueryDriver object OK');
     // Rebuild means rebuild the database for new tests
     $rebuild = true;
     $basedata = true;
     if (isset($annnotations['method']['rebuild'][0]) && $annnotations['method']['rebuild'][0] == 'false') {
         $rebuild = false;
     }
     if (isset($annnotations['method']['basedata'][0]) && $annnotations['method']['basedata'][0] == 'false') {
         $basedata = false;
     }
     if ($rebuild) {
         $builder = SqlBuilder::create($driver, array('rebuild' => true));
         $this->assertNotNull($builder);
         // $schemas = ClassUtils::schema_classes_to_objects($this->getModels());
         $schemas = ClassUtils::schema_classes_to_objects($this->getModels());
         foreach ($schemas as $schema) {
             $sqls = $builder->build($schema);
             $this->assertNotEmpty($sqls);
             foreach ($sqls as $sql) {
                 $dbh->query($sql);
             }
         }
         if ($basedata) {
             $runner = new SeedBuilder($this->config, $this->logger);
             foreach ($schemas as $schema) {
                 $runner->buildSchemaSeeds($schema);
             }
             if ($scripts = $this->config->getSeedScripts()) {
                 foreach ($scripts as $script) {
                     $runner->buildScriptSeed($script);
                 }
             }
         }
     }
 }
 public function getRuleLoader()
 {
     if ($this->ruleLoader) {
         return $this->ruleLoader;
     }
     $dataSource = $this->options['RuleLoader']['PDORuleLoader']['DataSource'];
     $connectionManager = ConnectionManager::getInstance();
     $conn = $connectionManager->getConnection($dataSource);
     $this->ruleLoader = new PDORuleLoader();
     $this->ruleLoader->load($conn);
     return $this->ruleLoader;
 }
Example #9
0
 public function setUp()
 {
     $annnotations = $this->getAnnotations();
     $connManager = ConnectionManager::getInstance();
     $dataSourceConfig = self::createDataSourceConfig($this->driver);
     if ($dataSourceConfig) {
         $connManager->addDataSource('default', $dataSourceConfig);
     } else {
         $this->markTestSkipped("{$this->driver} database configuration is missing.");
     }
     try {
         $dbh = $connManager->getConnection('default');
     } catch (PDOException $e) {
         $this->markTestSkipped('Can not connect to database, test skipped: ' . $e->getMessage());
         return;
     }
     $driver = ConnectionManager::getInstance()->getQueryDriver('default');
     ok($driver, 'QueryDriver object OK');
     // Rebuild means rebuild the database for new tests
     $rebuild = true;
     $basedata = true;
     if (isset($annnotations['method']['rebuild'][0]) && $annnotations['method']['rebuild'][0] == 'false') {
         $rebuild = false;
     }
     if (isset($annnotations['method']['basedata'][0]) && $annnotations['method']['basedata'][0] == 'false') {
         $basedata = false;
     }
     if ($rebuild) {
         $builder = SqlBuilder::create($driver, array('rebuild' => true));
         $this->assertNotNull($builder);
         // $schemas = ClassUtils::schema_classes_to_objects($this->getModels());
         $schemas = ClassUtils::schema_classes_to_objects($this->getModels());
         foreach ($schemas as $schema) {
             $sqls = $builder->build($schema);
             $this->assertNotEmpty($sqls);
             foreach ($sqls as $sql) {
                 $dbh->query($sql);
             }
         }
         if ($basedata) {
             $runner = new SeedBuilder($this->config, $this->logger);
             foreach ($schemas as $schema) {
                 $runner->buildSchemaSeeds($schema);
             }
             if ($scripts = $this->config->getSeedScripts()) {
                 foreach ($scripts as $script) {
                     $runner->buildScriptSeed($script);
                 }
             }
         }
     }
 }
Example #10
0
 public function register($kernel, $options = array())
 {
     $config = $kernel->config->stashes['database'];
     $loader = \LazyRecord\ConfigLoader::getInstance();
     if (!$loader->loaded) {
         $loader->load($config);
         $loader->init();
         // init data source and connection
     }
     $kernel->db = function () {
         return ConnectionManager::getInstance()->getConnection();
     };
 }
 public function register(Kernel $kernel, $options = array())
 {
     // TODO: move to generate prepare...
     $loader = \LazyRecord\ConfigLoader::getInstance();
     if (!$loader->loaded) {
         $loader->load($this->config);
         $loader->init();
         // init data source and connection
     }
     $kernel->db = function () {
         return ConnectionManager::getInstance()->getConnection('default');
     };
 }
 public function execute()
 {
     $dsId = $this->getCurrentDataSourceId();
     $connectionManager = ConnectionManager::getInstance();
     $conn = $connectionManager->getConnection($dsId);
     $driver = $connectionManager->getQueryDriver($dsId);
     $runner = new MigrationRunner($this->logger, $dsId);
     $runner->load($this->options->{'script-dir'} ?: 'db/migrations');
     $scripts = $runner->getUpgradeScripts($conn, $driver);
     $count = count($scripts);
     $this->logger->info('Found ' . $count . ($count > 1 ? ' migration scripts' : ' migration script') . ' to be executed.');
     foreach ($scripts as $script) {
         $this->logger->info('- ' . $script, 1);
     }
 }
Example #13
0
 public function execute()
 {
     $formatter = new \CLIFramework\Formatter();
     $options = $this->options;
     $logger = $this->logger;
     $connectionManager = \LazyRecord\ConnectionManager::getInstance();
     $dsId = $this->getCurrentDataSourceId();
     $conn = $connectionManager->getConnection($dsId);
     $driver = $connectionManager->getQueryDriver($dsId);
     $this->logger->info('Performing Comparison...');
     $parser = TableParser::create($driver, $conn);
     $existingTables = $parser->getTables();
     $tableSchemas = $parser->getDeclareSchemaMap();
     $found = false;
     $comparator = new Comparator();
     foreach ($tableSchemas as $table => $currentSchema) {
         $this->logger->debug("Checking table {$table}");
         $ref = new ReflectionObject($currentSchema);
         $filepath = $ref->getFilename();
         $filepath = substr($filepath, strlen(getcwd()) + 1);
         if (in_array($table, $existingTables)) {
             $before = $parser->reverseTableSchema($table);
             $diffs = $comparator->compare($before, $currentSchema);
             if (count($diffs)) {
                 $found = true;
                 $printer = new ComparatorConsolePrinter($diffs);
                 $printer->beforeName = $table . ":data source [{$dsId}]";
                 $printer->afterName = $table . ':' . $filepath;
                 $printer->output();
             }
         } else {
             $msg = sprintf("+ table %-20s %s", "'" . $table . "'", $filepath);
             echo $formatter->format($msg, 'green'), "\n";
             $a = isset($tableSchemas[$table]) ? $tableSchemas[$table] : null;
             $diff = $comparator->compare(new DeclareSchema(), $currentSchema);
             foreach ($diff as $diffItem) {
                 echo "  ", $diffItem->toColumnAttrsString(), "\n";
             }
             $found = true;
         }
     }
     if (!$found) {
         $this->logger->info("No diff found");
     }
 }
 public function insertIntoDataSource($schema)
 {
     $connManager = LazyRecord\ConnectionManager::getInstance();
     $configLoader = ConfigLoader::getInstance();
     $configLoader->loadFromSymbol(true);
     $connManager->init($configLoader);
     $pdo = $connManager->getConnection(self::getCurrentDriverType());
     $this->assertInstanceOf('PDO', $pdo);
     $queryDriver = $connManager->getQueryDriver(self::getCurrentDriverType());
     $builder = SqlBuilder::create($queryDriver, array('rebuild' => true));
     $builder->build($schema);
     $sqls = $builder->build($schema);
     $this->assertNotEmpty($sqls);
     foreach ($sqls as $sql) {
         $this->assertQueryOK($pdo, $sql);
     }
     $this->assertTableExists($pdo, $schema->getTable());
 }
 /**
  * @dataProvider driverTypeDataProvider
  */
 public function testTableParserFor($driverType)
 {
     $config = self::createNeutralConfigLoader();
     $manager = ConnectionManager::getInstance();
     $manager->free();
     $this->registerDataSource($driverType);
     $conn = $manager->getConnection($driverType);
     $driver = $manager->getQueryDriver($driverType);
     $parser = TableParser::create($driver, $conn);
     $tables = $parser->getTables();
     $this->assertNotNull($tables);
     foreach ($tables as $table) {
         $this->assertNotNull($table);
         $schema = $parser->reverseTableSchema($table);
         $this->assertNotNull($schema);
         $columns = $schema->getColumns();
         $this->assertNotEmpty($columns);
     }
 }
 public function testMigrationByDiff()
 {
     if ($this->getDriverType() == 'sqlite') {
         $this->markTestSkipped('sqlite migration tests skipped');
         return;
     }
     $connectionManager = ConnectionManager::getInstance();
     $pdo = $connectionManager->getConnection($this->getDriverType());
     $pdo->query('DROP TABLE IF EXISTS users');
     $pdo->query('DROP TABLE IF EXISTS test');
     $pdo->query('CREATE TABLE users (account VARCHAR(128) UNIQUE)');
     if (!file_exists('tests/migrations_testing')) {
         mkdir('tests/migrations_testing');
     }
     $generator = new MigrationGenerator(Console::getInstance()->getLogger(), 'tests/migrations_testing');
     ok(class_exists('TestApp\\Model\\UserSchema', true));
     $finder = new SchemaFinder();
     $finder->find();
     list($class, $path) = $generator->generateWithDiff('DiffMigration', $this->getDriverType(), [new TestApp\Model\UserSchema()], '20120101');
     require_once $path;
     ok($class::getId());
     /*
     $userSchema = new TestApp\Model\UserSchema;
     $column = $userSchema->getColumn('account');
     */
     /*
      */
     // run migration
     $runner = new MigrationRunner($this->getDriverType());
     $runner->resetMigrationId($this->getDriverType());
     $runner->load('tests/migrations_testing');
     // XXX: PHPUnit can't run this test in separated unit test since
     // there is a bug of serializing the global array, this assertion will get 5 instead of the expected 1.
     $scripts = $runner->getMigrationScripts();
     $this->assertNotEmpty($scripts);
     // $this->assertCount(1, $scripts);
     // $this->expectOutputRegex('#DiffMigration_1325347200#');
     $runner->runUpgrade([$class]);
     # echo file_get_contents($path);
     unlink($path);
     $pdo->query('DROP TABLE IF EXISTS users');
 }
Example #17
0
 public function __construct($name = null, array $data = array(), $dataName = '')
 {
     parent::__construct($name, $data, $dataName);
     if (!extension_loaded('pdo')) {
         return $this->markTestSkipped('pdo extension is required for model testing');
     }
     // The config loader is used to initialize connection manager
     $this->config = ConfigLoader::getInstance();
     $this->config->loadFromSymbol(true);
     $this->config->setDefaultDataSourceId($this->getDataSource());
     // Always true
     $configStash = $this->config->getConfigStash();
     $cnofigStash['schema']['auto_id'] = true;
     // free and override default connection
     $this->connManager = ConnectionManager::getInstance();
     $this->connManager->init($this->config);
     // $config = self::createNeutralConfigLoader();
     $this->logger = new Logger();
     $this->logger->setQuiet();
 }
Example #18
0
 /**
  * Get PDO connection for reading data.
  *
  * @return PDO
  */
 public function getReadConnection()
 {
     return ConnectionManager::getInstance()->getConnection($this->getReadSourceId());
 }
Example #19
0
 /**
  * load data sources to connection manager
  */
 public function loadDataSources()
 {
     // load data source into connection manager
     $manager = ConnectionManager::getInstance();
     foreach ($this->getDataSources() as $sourceId => $ds) {
         $manager->addDataSource($sourceId, $ds);
     }
 }
Example #20
0
 public function registerDataSource($driverType)
 {
     $connManager = ConnectionManager::getInstance();
     if ($dataSource = BaseTestCase::createDataSourceConfig($driverType)) {
         $connManager->addDataSource($driverType, $dataSource);
     } else {
         $this->markTestSkipped("Data source for {$driverType} is undefined");
     }
 }
Example #21
0
 /**
  * Get PDO connection for reading data.
  *
  * @return PDO
  */
 public function getReadConnection()
 {
     return $this->_readConnection ? $this->_readConnection : ($this->_readConnection = ConnectionManager::getInstance()->getConnection($this->readSourceId));
 }
Example #22
0
 public function tearDown()
 {
     $connm = ConnectionManager::getInstance();
     $connm->removeDataSource('default');
     $connm->close('default');
 }
Example #23
0
 /**
  * load data sources to connection manager
  */
 public function loadDataSources()
 {
     // load data source into connection manager
     $manager = ConnectionManager::getInstance();
     $manager->init($this);
 }
 public function generateWithDiff($taskName, $dataSourceId, array $schemas, $time = null)
 {
     $connectionManager = \LazyRecord\ConnectionManager::getInstance();
     $connection = $connectionManager->getConnection($dataSourceId);
     $driver = $connectionManager->getQueryDriver($dataSourceId);
     $parser = TableParser::create($connection, $driver);
     $tableSchemas = $schemas;
     $existingTables = $parser->getTables();
     $this->logger->info('Found ' . count($schemas) . ' schemas to compare.');
     $template = $this->createClassTemplate($taskName, $time);
     $upgradeMethod = $template->addMethod('public', 'upgrade', array(), '');
     $downgradeMethod = $template->addMethod('public', 'downgrade', array(), '');
     $comparator = new Comparator($driver);
     // schema from runtime
     foreach ($tableSchemas as $key => $a) {
         $table = is_numeric($key) ? $a->getTable() : $key;
         if (!in_array($table, $existingTables)) {
             $this->logger->info(sprintf("Found schema '%s' to be imported to '%s'", $a, $table), 1);
             // generate create table statement.
             // use sqlbuilder to build schema sql
             $upcall = new MethodCallExpr('$this', 'importSchema', [new Raw('new ' . get_class($a))]);
             $upgradeMethod->getBlock()->appendLine(new Statement($upcall));
             $downcall = new MethodCallExpr('$this', 'dropTable', [$table]);
             $downgradeMethod->getBlock()->appendLine(new Statement($downcall));
             continue;
         }
         // revsersed schema
         $b = $parser->reverseTableSchema($table, $a);
         $diffs = $comparator->compare($b, $a);
         if (empty($diffs)) {
             continue;
         }
         // generate alter table statement.
         foreach ($diffs as $diff) {
             switch ($diff->flag) {
                 case 'A':
                     $alterTable = new AlterTableQuery($table);
                     $alterTable->addColumn($diff->getAfterColumn());
                     $this->appendQueryStatement($upgradeMethod, $driver, $alterTable, new ArgumentArray());
                     $alterTable = new AlterTableQuery($table);
                     $alterTable->dropColumn($diff->getAfterColumn());
                     $this->appendQueryStatement($downgradeMethod, $driver, $alterTable, new ArgumentArray());
                     break;
                 case 'M':
                     $alterTable = new AlterTableQuery($table);
                     $after = $diff->getAfterColumn();
                     $before = $diff->getBeforeColumn();
                     if (!$after || !$before) {
                         throw new LogicException('afterColumn or beforeColumn is undefined.');
                     }
                     // Check primary key
                     if ($before->primary != $after->primary) {
                         // primary key requires another sub-statement "ADD PRIMARY KEY .."
                         $alterTable->add()->primaryKey([$after->name]);
                     }
                     $alterTable->modifyColumn($after);
                     $this->appendQueryStatement($upgradeMethod, $driver, $alterTable, new ArgumentArray());
                     $alterTable = new AlterTableQuery($table);
                     $alterTable->modifyColumn($before);
                     $this->appendQueryStatement($downgradeMethod, $driver, $alterTable, new ArgumentArray());
                     break;
                 case 'D':
                     $alterTable = new AlterTableQuery($table);
                     $alterTable->dropColumnByName($diff->name);
                     $this->appendQueryStatement($upgradeMethod, $driver, $alterTable, new ArgumentArray());
                     $alterTable = new AlterTableQuery($table);
                     $alterTable->addColumn($diff->getBeforeColumn());
                     $this->appendQueryStatement($downgradeMethod, $driver, $alterTable, new ArgumentArray());
                     break;
                 default:
                     $this->logger->warn('** unsupported flag.');
                     continue;
             }
         }
     }
     $filename = $this->generateFilename($taskName, $time);
     $path = $this->migrationDir . DIRECTORY_SEPARATOR . $filename;
     if (false === file_put_contents($path, $template->render())) {
         throw new RuntimeException("Can't write migration script to {$path}.");
     }
     return array($template->class->name, $path);
 }
Example #25
0
 public function __construct($name = NULL, array $data = array(), $dataName = '')
 {
     parent::__construct($name, $data, $dataName);
     if (!extension_loaded('pdo')) {
         $this->markTestSkipped('pdo extension is required for model testing');
         return;
     }
     // free and override default connection
     ConnectionManager::getInstance()->free();
     $config = self::createNeutralConfigLoader();
     $this->setConfig($config);
     $this->logger = new Logger();
     $this->logger->setQuiet();
     if (method_exists($this, 'getModels')) {
         $generator = new SchemaGenerator($this->config, $this->logger);
         $schemas = ClassUtils::schema_classes_to_objects($this->getModels());
         $classMap = $generator->generate($schemas);
     }
 }
Example #26
0
<?php

use LazyRecord\Schema\SchemaGenerator;
use LazyRecord\Schema\SchemaLoader;
use LazyRecord\ConfigLoader;
use LazyRecord\ConnectionManager;
define('ROOT', dirname(__DIR__));
$loader = (require ROOT . '/vendor/autoload.php');
$loader->add(null, ROOT . '/tests');
$config = ConfigLoader::getInstance();
$config->loadFromArray(array('bootstrap' => ['tests/bootstrap.php'], 'schema' => ['auto_id' => 1, 'paths' => ['tests']], 'data_source' => ['default' => 'sqlite', 'nodes' => ['sqlite' => ['dsn' => 'sqlite::memory:', 'user' => NULL, 'pass' => NULL]]]));
$connectionManager = ConnectionManager::getInstance();
$connectionManager->init($config);
$logger = new CLIFramework\Logger();
// $logger->setQuiet();
$logger->info("Updating schema class files...");
$schemas = array(new \User\Model\UserSchema(), new \OrderBundle\Model\OrderSchema(), new \OrderBundle\Model\OrderItemSchema());
$g = new \LazyRecord\Schema\SchemaGenerator($config, $logger);
$g->setForceUpdate(true);
$g->generate($schemas);
/**
 * Clean up cache files
 */
const CACHE_DIR = 'src/ActionKit/Cache';
const UPLOAD_DIR = 'tests/upload';
if (file_exists(CACHE_DIR)) {
    futil_rmtree(CACHE_DIR);
    mkdir(CACHE_DIR, 0755, true);
} else {
    mkdir(CACHE_DIR, 0755, true);
}
Example #27
0
 public function getCurrentConnection()
 {
     $dataSource = $this->getCurrentDataSourceId();
     $connectionManager = ConnectionManager::getInstance();
     return $connectionManager->getConnection($dataSource);
 }
 public function generateWithDiff($taskName, $dataSourceId, $schemas, $time = null)
 {
     $connectionManager = \LazyRecord\ConnectionManager::getInstance();
     $connection = $connectionManager->getConnection($dataSourceId);
     $driver = $connectionManager->getQueryDriver($dataSourceId);
     $parser = TableParser::create($driver, $connection);
     $tableSchemas = $parser->getTableSchemaMap();
     $this->logger->info('Found ' . count($schemas) . ' schemas to compare.');
     $template = $this->createClassTemplate($taskName, $time);
     $template->useClass('SQLBuilder\\Universal\\Syntax\\Column');
     $upgradeMethod = $template->addMethod('public', 'upgrade', array(), '');
     $downgradeMethod = $template->addMethod('public', 'downgrade', array(), '');
     $comparator = new Comparator();
     // schema from runtime
     foreach ($schemas as $b) {
         $tableName = $b->getTable();
         $foundTable = isset($tableSchemas[$tableName]);
         if ($foundTable) {
             $a = $tableSchemas[$tableName];
             // schema object, extracted from database.
             $diffs = $comparator->compare($a, $b);
             // generate alter table statement.
             foreach ($diffs as $diff) {
                 if ($diff->flag == 'A') {
                     $this->logger->info(sprintf("'%s': add column %s", $tableName, $diff->name), 1);
                     $column = $diff->getAfterColumn();
                     $upcall = new MethodCallExpr('$this', 'addColumn', [$tableName, $column]);
                     $upgradeMethod[] = new Statement($upcall);
                     $downcall = new MethodCallExpr('$this', 'dropColumnByName', [$tableName, $diff->name]);
                     $downgradeMethod[] = new Statement($downcall);
                 } else {
                     if ($diff->flag == 'D') {
                         $upcall = new MethodCallExpr('$this', 'dropColumnByName', [$tableName, $diff->name]);
                         $upgradeMethod->getBlock()->appendLine(new Statement($upcall));
                     } else {
                         if ($diff->flag == 'M') {
                             if ($afterColumn = $diff->getAfterColumn()) {
                                 $upcall = new MethodCallExpr('$this', 'modifyColumn', [$tableName, $afterColumn]);
                                 $upgradeMethod[] = new Statement($upcall);
                             } else {
                                 throw new \Exception("afterColumn is undefined.");
                             }
                             continue;
                         } else {
                             $this->logger->warn("** unsupported flag.");
                             continue;
                         }
                     }
                 }
             }
         } else {
             $this->logger->info(sprintf("Found schema '%s' to be imported to '%s'", $b, $tableName), 1);
             // generate create table statement.
             // use sqlbuilder to build schema sql
             $upcall = new MethodCallExpr('$this', 'importSchema', [new Raw('new ' . get_class($b))]);
             $upgradeMethod->getBlock()->appendLine(new Statement($upcall));
             $downcall = new MethodCallExpr('$this', 'dropTable', [$tableName]);
             $downgradeMethod->getBlock()->appendLine(new Statement($downcall));
         }
     }
     $filename = $this->generateFilename($taskName, $time);
     $path = $this->migrationDir . DIRECTORY_SEPARATOR . $filename;
     if (false === file_put_contents($path, $template->render())) {
         throw new RuntimeException("Can't write migration script to {$path}.");
     }
     return array($template->class->name, $path);
 }
Example #29
0
 /**
  * Load Collection from a SQL query statement.
  *
  * @param string $sql
  * @param array $args
  * @param string $dsId
  */
 public function loadQuery($sql, array $args = array(), $dsId = null)
 {
     if (!$dsId) {
         $dsId = $this->getSchema()->getReadSourceId();
     }
     $this->handle = ConnectionManager::getInstance()->getConnection($dsId)->prepareAndExecute($sql, $args);
 }
 public static function create(DeclareSchema $schema, $baseClass)
 {
     $cTemplate = new ClassFile($schema->getBaseModelClass());
     $cTemplate->useClass('LazyRecord\\Schema\\SchemaLoader');
     $cTemplate->useClass('LazyRecord\\Result');
     $cTemplate->useClass('SQLBuilder\\Bind');
     $cTemplate->useClass('SQLBuilder\\ArgumentArray');
     $cTemplate->useClass('PDO');
     $cTemplate->useClass('SQLBuilder\\Universal\\Query\\InsertQuery');
     $cTemplate->addConsts(array('SCHEMA_PROXY_CLASS' => $schema->getSchemaProxyClass(), 'COLLECTION_CLASS' => $schema->getCollectionClass(), 'MODEL_CLASS' => $schema->getModelClass(), 'TABLE' => $schema->getTable(), 'READ_SOURCE_ID' => $schema->getReadSourceId(), 'WRITE_SOURCE_ID' => $schema->getWriteSourceId(), 'PRIMARY_KEY' => $schema->primaryKey));
     $cTemplate->addProtectedProperty('table', $schema->getTable());
     $cTemplate->addPublicProperty('readSourceId', $schema->getReadSourceId() ?: 'default');
     $cTemplate->addPublicProperty('writeSourceId', $schema->getWriteSourceId() ?: 'default');
     $cTemplate->addMethod('public', 'getSchema', [], ['if ($this->_schema) {', '   return $this->_schema;', '}', 'return $this->_schema = SchemaLoader::load(' . var_export($schema->getSchemaProxyClass(), true) . ');']);
     $cTemplate->addStaticVar('column_names', $schema->getColumnNames());
     $cTemplate->addStaticVar('column_hash', array_fill_keys($schema->getColumnNames(), 1));
     $cTemplate->addStaticVar('mixin_classes', array_reverse($schema->getMixinSchemaClasses()));
     if ($traitClasses = $schema->getModelTraitClasses()) {
         foreach ($traitClasses as $traitClass) {
             $cTemplate->useTrait($traitClass);
         }
     }
     $schemaReflection = new ReflectionClass($schema);
     $schemaDocComment = $schemaReflection->getDocComment();
     // TODO: apply settings from schema...
     $codegenSettings = [];
     preg_match_all('/@codegen (\\w+)(?:\\s*=\\s*(\\S+))?$/m', $schemaDocComment, $allMatches);
     for ($i = 0; $i < count($allMatches[0]); $i++) {
         $key = $allMatches[1][$i];
         $value = $allMatches[2][$i];
         if ($value === "") {
             $value = true;
         } else {
             if (strcasecmp($value, "true") == 0 || strcasecmp($value, "false") == 0) {
                 $value = filter_var($value, FILTER_VALIDATE_BOOLEAN);
             } else {
                 if (preg_match('/^\\d+$/', $value)) {
                     $value = intval($value);
                 }
             }
         }
         $codegenSettings[$key] = $value;
     }
     /*
     if ($codegenSettings['validateColumn']) {
         $codegenSettings['handleValidationError'] = true;
     }
     */
     if (!empty($codegenSettings)) {
         $reflectionModel = new ReflectionClass('LazyRecord\\BaseModel');
         $createMethod = $reflectionModel->getMethod('create');
         $methodFile = $createMethod->getFilename();
         $startLine = $createMethod->getStartLine();
         $endLine = $createMethod->getEndLine();
         $lines = file($methodFile);
         $methodLines = array_slice($lines, $startLine + 1, $endLine - $startLine - 2);
         // exclude '{', '}'
         $blockRanges = array();
         $blockLines = array();
         // parse code blocks
         for ($i = 0; $i < count($methodLines); $i++) {
             $line = rtrim($methodLines[$i]);
             if (preg_match('/@codegenBlock (\\w+)/', $line, $matches)) {
                 $blockId = $matches[1];
                 for ($j = $i; $j < count($methodLines); $j++) {
                     $line = rtrim($methodLines[$j]);
                     $blockLines[$blockId][] = $line;
                     if (preg_match('/@codegenBlockEnd/', $line)) {
                         $blockRanges[$blockId] = [$i, $j];
                         $i = $j;
                         break;
                     }
                 }
             }
         }
         $overrideCreateMethod = $cTemplate->addMethod('public', 'create', ['array $args', 'array $options = array()']);
         $overrideBlock = $overrideCreateMethod->getBlock();
         for ($i = 0; $i < count($methodLines); $i++) {
             $line = rtrim($methodLines[$i]);
             if (preg_match('/@codegenBlock (\\w+)/', $line, $matches)) {
                 $blockId = $matches[1];
                 if (isset($codegenSettings[$matches[1]]) && isset($blockLines[$blockId])) {
                     if ($codegenSettings[$matches[1]]) {
                         $overrideBlock[] = $blockLines[$blockId];
                         list($startLine, $endLine) = $blockRanges[$blockId];
                         $i = $endLine;
                         continue;
                     } else {
                         list($startLine, $endLine) = $blockRanges[$blockId];
                         $i = $endLine;
                         continue;
                     }
                 }
             }
             $overrideBlock[] = $line;
         }
     }
     // TODO: refacory this into factory method
     // Generate findByPrimaryKey SQL query
     $arguments = new ArgumentArray();
     $findByPrimaryKeyQuery = new SelectQuery();
     $findByPrimaryKeyQuery->from($schema->getTable());
     $primaryKey = $schema->primaryKey;
     $readFrom = $schema->getReadSourceId();
     $readConnection = ConnectionManager::getInstance()->getConnection($readFrom);
     $readQueryDriver = $readConnection->createQueryDriver();
     $primaryKeyColumn = $schema->getColumn($primaryKey);
     $findByPrimaryKeyQuery->select('*')->where()->equal($primaryKey, new Bind($primaryKey));
     $findByPrimaryKeyQuery->limit(1);
     $findByPrimaryKeySql = $findByPrimaryKeyQuery->toSql($readQueryDriver, $arguments);
     $cTemplate->addConst('FIND_BY_PRIMARY_KEY_SQL', $findByPrimaryKeySql);
     foreach ($schema->getColumns() as $column) {
         if (!$column->findable) {
             continue;
         }
         $columnName = $column->name;
         $findMethodName = 'findBy' . ucfirst(Inflector::camelize($columnName));
         $findMethod = $cTemplate->addMethod('public', $findMethodName, ['$value']);
         $block = $findMethod->block;
         $arguments = new ArgumentArray();
         $findByColumnQuery = new SelectQuery();
         $findByColumnQuery->from($schema->getTable());
         $columnName = $column->name;
         $readFrom = $schema->getReadSourceId();
         $findByColumnQuery->select('*')->where()->equal($columnName, new Bind($columnName));
         $findByColumnQuery->limit(1);
         $findByColumnSql = $findByColumnQuery->toSql($readQueryDriver, $arguments);
         $block[] = '$conn  = $this->getReadConnection();';
         $block[] = 'if (!isset($this->_preparedFindStms[' . var_export($columnName, true) . '])) {';
         $block[] = '    $this->_preparedFindStms[' . var_export($columnName, true) . '] = $conn->prepare(' . var_export($findByColumnSql, true) . ');';
         $block[] = '}';
         $block[] = '$this->_preparedFindStms[' . var_export($columnName, true) . ']->execute([' . var_export(":{$columnName}", true) . ' => $value ]);';
         $block[] = 'if (false === ($this->_data = $this->_preparedFindStms[' . var_export($columnName, true) . ']->fetch(PDO::FETCH_ASSOC)) ) {';
         $block[] = '    return $this->reportError("Record not found", [';
         $block[] = '        "sql" => ' . var_export($findByColumnSql, true) . ',';
         $block[] = '    ]);';
         $block[] = '}';
         $block[] = '$this->_preparedFindStms[' . var_export($columnName, true) . ']->closeCursor();';
         $block[] = 'return $this->reportSuccess( "Data loaded", array( ';
         $block[] = '    "sql" => ' . var_export($findByColumnSql, true) . ',';
         $block[] = '    "type" => Result::TYPE_LOAD,';
         $block[] = '));';
     }
     $cTemplate->extendClass('\\' . $baseClass);
     // interfaces
     if ($ifs = $schema->getModelInterfaces()) {
         foreach ($ifs as $iface) {
             $cTemplate->implementClass($iface);
         }
     }
     // Create column accessor
     if ($schema->enableColumnAccessors) {
         foreach ($schema->getColumnNames() as $columnName) {
             $accessorMethodName = 'get' . ucfirst(Inflector::camelize($columnName));
             $cTemplate->addMethod('public', $accessorMethodName, [], ['    return $this->get(' . var_export($columnName, true) . ');']);
         }
     }
     return $cTemplate;
 }