diff --git a/bin/load.php b/bin/load.php index 2fa90b5..aeb326a 100644 --- a/bin/load.php +++ b/bin/load.php @@ -2,6 +2,7 @@ namespace joshmoody\Mock\Bin; +use Illuminate\Support\Facades\Schema; use joshmoody\Mock\Models\Database; use joshmoody\Mock\Models\LastName; use joshmoody\Mock\Models\FirstName; @@ -23,7 +24,7 @@ Database::init($opts); // Disable query log so we don't run out of memory logging all these inserts. -DB::disableQueryLog(); +DB::connection('mock-data')->disableQueryLog(); function get_filename($file) { @@ -50,9 +51,9 @@ function extract_datafiles() function load_lastnames($limit = 500) { - if (!DB::schema()->hasTable('last_names')) + if (!DB::schema('mock-data')->hasTable('last_names')) { - DB::schema()->create('last_names', function($table) + DB::schema('mock-data')->create('last_names', function($table) { # Define some fields. $table->increments('id'); @@ -100,9 +101,9 @@ function load_lastnames($limit = 500) function load_firstnames($limit = 500) { - if (!DB::schema()->hasTable('first_names')) + if (!DB::schema('mock-data')->hasTable('first_names')) { - DB::schema()->create('first_names', function($table) + DB::schema('mock-data')->create('first_names', function($table) { # Define the fields. $table->increments('id'); @@ -193,9 +194,9 @@ function load_male_firstnames($limit = 500) function load_streets() { - if (!DB::schema()->hasTable('streets')) + if (!DB::schema('mock-data')->hasTable('streets')) { - DB::schema()->create('streets', function($table) + DB::schema('mock-data')->create('streets', function($table) { # Define some fields. $table->increments('id'); @@ -231,9 +232,9 @@ function load_streets() function load_zipcodes() { - DB::schema()->dropIfExists('zipcodes'); - - DB::schema()->create('zipcodes', function($table) + DB::schema('mock-data')->dropIfExists('zipcodes'); + + DB::schema('mock-data')->create('zipcodes', function($table) { # Define some fields. $table->increments('id'); @@ -276,6 +277,7 @@ function load_zipcodes() $counter = 0; // Total number records processed. $loaded = 0; // Number records actually loaded. + while(!feof($fp)) { $counter++; @@ -299,7 +301,7 @@ function load_zipcodes() $notes ) = fgetcsv($fp); - // Skip heading row and everyting but standard zip codes for the 50 states and DC + // Skip heading row and everything but standard zip codes for the 50 states and DC if ($counter > 1 && $type == 'STANDARD' && !in_array($state_code, ['GU','PR','VI'])) { $loaded++; @@ -349,4 +351,4 @@ function load_zipcodes() $loaded = load_zipcodes(); print "Loaded $loaded zipcodes\n"; -DB::enableQueryLog(); \ No newline at end of file +DB::connection('mock-data')->enableQueryLog(); diff --git a/composer.json b/composer.json index 52466da..70ba8da 100644 --- a/composer.json +++ b/composer.json @@ -19,8 +19,8 @@ "require": { "php": ">= 5.4", - "illuminate/database": "*", - "prelude/prelude-dsn": "*" + "illuminate/database": "4.2.*@dev", + "prelude/prelude-database": "0.0.3" }, "require-dev": { diff --git a/data/database.sqlite b/data/database.sqlite index 1d35afe..ead30ee 100644 Binary files a/data/database.sqlite and b/data/database.sqlite differ diff --git a/src/Models/Database.php b/src/Models/Database.php index 90504d1..6bf1fb8 100644 --- a/src/Models/Database.php +++ b/src/Models/Database.php @@ -3,12 +3,18 @@ namespace joshmoody\Mock\Models; use Illuminate\Database\Capsule\Manager as Capsule; -use Prelude\Dsn\DsnParser; +use Illuminate\Database\Eloquent\Builder as QueryBuilder; +use Prelude\Database\DsnParser; class Database { - public static $driver = null; - + public static $driver = []; + + /** + * Initialize the connection to the database. + * + * @param null $config + */ public static function init($config = null) { $defaults = [ @@ -21,47 +27,152 @@ public static function init($config = null) 'collation' => 'utf8_unicode_ci', 'prefix' => null ]; - + $capsule = new Capsule; - + + if (is_string($config)) { + $config = self::parseDsn($config); + } + if (is_array($config)) { - $options = array_merge($defaults, $config); + + // missing 'driver' key, so it must be an array of arrays + if (!array_key_exists('driver', $config)) { + + // if we have an array of connections, iterate through them. connections should be stored in the form of name => conn_info + foreach ($config as $connection_name => $connection_info) { + + // if it's a dsn string, then parse it + if (is_string($connection_info)) { + $connection_info = self::parseDsn($connection_info); + } + + // now merge it into our options + $options[$connection_name] = array_merge($defaults, $connection_info); + } + } else { + $options['mock-data'] = array_merge($defaults, $config); + } } else { - $options = $defaults; + $options['mock-data'] = $defaults; } - - $capsule->addConnection($options); + + // add each connection, then set as global and boot + foreach ($options as $name => $info) { + $capsule->addConnection($info, $name); + self::$driver[$name] = $info['driver']; + } + $capsule->setAsGlobal(); $capsule->bootEloquent(); - - self::$driver = $options['driver']; + + // determine if we should log queries or not + foreach ($options as $name => $info) { + + // make sure we use FALSE to disable queries, otherwise it'll just default to logging queries + if (isset($info['log_queries']) && $info['log_queries'] === false) { + Capsule::connection($name)->disableQueryLog(); + } else { + Capsule::connection($name)->enableQueryLog(); + } + } } - - public static function random() + + /** + * Return the name of the random function based on the SQL dialect being used. + * + * @param string $connection_name + * @return string + */ + public static function random($connection_name = 'mock-data') { - if (self::$driver == 'sqlite') { + if (self::$driver[$connection_name] == 'sqlite') { return 'random()'; } else { return 'rand()'; } } - + + /** + * Take a string DSN and parse it into an array of its pieces + * + * @param null $string + * @return array|null + */ public static function parseDsn($string = null) { $opts = null; - + if (!empty($string)) { $dsn = (object) DsnParser::parseUrl($string)->toArray(); - + $opts = [ 'driver' => $dsn->driver, 'host' => $dsn->host, 'database' => $dsn->dbname, 'username' => $dsn->user, - 'password' => $dsn->pass + 'password' => isset($dsn->pass) ? $dsn->pass : null ]; } return $opts; } + + /** + * Get a preview of what query will be run from a query builder. + * + * This DOES NOT run the query so it can be used for debugging potentially memory-intensive queries. + * + * @param QueryBuilder $query + * @return string + */ + public static function getQueryPreview(QueryBuilder $query = null) + { + if (empty($query)) { + return ""; + } + + $sql = str_replace('?', "'%s'", $query->toSql()); + $bindings = $query->getBindings(); + + return vsprintf($sql, $bindings); + } + + /** + * Get the last query that was run with data that was used bound to it. + * + * @param string $connection + * @return string + */ + public static function getLastQuery($connection = "") + { + $last_query = ""; + $pretty_queries = self::getPrettyQueryLog($connection); + + if (!empty($pretty_queries)) { + $last_query = $pretty_queries[ count($pretty_queries) - 1 ]; + } + + return $last_query; + } + + /** + * Get a list of all queries formatted with their bindings in place + * + * @param string $connection + * @return array + */ + public static function getPrettyQueryLog($connection = "") + { + $return_queries = []; + + $queries = Capsule::connection($connection)->getQueryLog(); + + foreach ($queries as $query) { + $query_pattern = str_replace('?', "'%s'", $query['query']); + $return_queries[] = vsprintf($query_pattern, $query['bindings']); + } + + return $return_queries; + } } diff --git a/src/Models/FirstName.php b/src/Models/FirstName.php index 10da3ab..b810b37 100644 --- a/src/Models/FirstName.php +++ b/src/Models/FirstName.php @@ -6,5 +6,6 @@ class FirstName extends Model { + public $connection = 'mock-data'; public $timestamps = false; } diff --git a/src/Models/LastName.php b/src/Models/LastName.php index 1eaaf9b..00b0a32 100644 --- a/src/Models/LastName.php +++ b/src/Models/LastName.php @@ -6,5 +6,6 @@ class LastName extends Model { + public $connection = 'mock-data'; public $timestamps = false; } diff --git a/src/Models/Street.php b/src/Models/Street.php index 208702d..8d6d806 100644 --- a/src/Models/Street.php +++ b/src/Models/Street.php @@ -6,5 +6,6 @@ class Street extends Model { + public $connection = 'mock-data'; public $timestamps = false; } diff --git a/src/Models/Zipcode.php b/src/Models/Zipcode.php index c4bf58e..846b695 100644 --- a/src/Models/Zipcode.php +++ b/src/Models/Zipcode.php @@ -6,5 +6,6 @@ class Zipcode extends Model { + public $connection = 'mock-data'; public $timestamps = false; }