Create new database and tables on the fly - php

I was reading the post "Create new database and tables on the fly"
I tried to implement an updated version of the create schema function:
public static function createSchema($schemaName)
{
$dbName = "db_{$schemaName}";
return DB::getSchemaBuilder()
->getConnection()
->statement("CREATE DATABASE :schema", ['schema' => $dbName ]);
}
but I get the following error:
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '?' at line 1 (SQL: CREATE DATABASE :schema)
PDO does not allowed to bind params on a create database query. So i'm not sure how to create DB's on the fly as safely as possible. Can anyone show me the way, before i have to introduce a security flaw in our site.

You cannot use bindings with CREATE DATABASE and PDO, because in CREATE DATABASE foo, foo isn't a quoted identifier, it's a raw new database name. You'll need to do any sanity checking yourself rather than relying on parameter binding to protect you.
public static function createSchema($schemaName)
{
$dbName = "db_{$schemaName}";
$quotedDbName = preg_replace("/[^_a-zA-Z0-9]+/", "", $dbName);
return DB::statement("CREATE DATABASE $quotedDbName");
}
See this question for more details about CREATE DATABASE with PDO binding.

public static function createSchema($schemaName)
{
// We will use the `statement` method from the connection class so that
// we have access to parameter binding.
return DB::getConnection()->statement('CREATE DATABASE :schema', ['schema' => 'db_' . $schemaName]);
}
i believe you dont need schema builder here

Related

Where JSON in Laravel gives error SQLSTATE[42000]: check the manual that corresponds to your MariaDB server

I have tried to get data from database with laravel Where JSON. But it gives an error. I have added the data like this.
$event = new Event;
$event->scores = json_encode([['user_ids' => [1,2,3,4],'score' => 15]]);
$event->save();
When I want to return the data in database.
Event::where('scores->score',15)->get()
Shows this error:
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an
error in your SQL syntax; check the manual that corresponds to your
MariaDB server version for the right syntax to use near '>'$."score"'
= ?' at line 1 (SQL: select * from `events` where `scores`->'$."score"' = 15)
My MariaDB version is 10.2.1
Array & JSON Casting
On your Event model you need to add
class Event extends Model {
protected $casts = ['scores'=>'array'];
// ...
}
and then when saving the data
$event = new Event;
// you had what appeared to be an extra array, that could cause the issue?
$event->scores = ['user_ids' => [1,2,3,4],'score' => 15];
$event->save();
Then the data will be saved as JSON automatically as long as the column type is TEXT or JSON(new versions of MySQL).
See Array & JSON casting on the Laravel Documentation: https://laravel.com/docs/5.5/eloquent-mutators#array-and-json-casting
Then to retrieve:
Event::where('scores->score', '15')->get();
Here is the relevant documentation for JSON Where clauses
https://laravel.com/docs/5.5/queries#json-where-clauses
Again, pretty confused as to what you are asking. Might help to see structure of the table or what the expected SQL should look like.
If you are trying to return rows based off values contained inside a string of JSON stored on the table... Then you need to do something like...
->whereRaw("JSON_CONTAINS(score, '[15]' )")->get();
Or something along those lines... https://dev.mysql.com/doc/refman/5.7/en/json-search-functions.html

PDO doesn't seem to create MySQL database

I'm trying to create a database using the following code:
// Set up DB connection and creates the DB
try {
$connection = new \PDO(
'mysql:host='.Settings\Database::$host.';',
Settings\Database::$username,
Settings\Database::$password);
$connection->exec("CREATE DATABASE IF NOT EXISTS ".Settings\Database::$databaseName." CHARACTER SET utf8 COLLATION utf8_unicode_ci;");
} catch (\PDOException $exception) {
die("Could not connect to database: ".$exception->getMessage());
}
The problem is that no database is being created and I receive no error except for the fact that when I try create a table with PDO i receive this error:
READ EDIT 2
Could not connect to database: SQLSTATE[HY000] [1049] Unknown database 'dbname'
Edit:
I have no problem manually creating the DB with phpMyAdmin and similars.
Edit 2:
Mistakenly I thought that the error was given by the CREATE TABLE... statement. Instead the error is returned by the die() function in the exception handling.
Your call to exec() isn't throwing exceptions. You have to enable that for each PDO connection with an attribute like this:
$connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
If you were getting the error message from exec(), you would have seen this:
Could not connect to database: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'COLLATION utf8_unicode_ci' at line 1
The syntax for CREATE DATABASE uses the keyword COLLATE, not COLLATION.
See http://dev.mysql.com/doc/refman/5.6/en/create-database.html

Transfer mysql table between two databases with PDO

I have been researching this for the past hour, and yet to come up with a simple solution that doesnt involve some weird exports/imports.
All I am trying to do is open up a PDO connection with two databases so that I can use them both in queries.
It seems that there is disagreements in Stack Overflow about this.
One answer:
...you will need to create two PDO objects for the seperate
connections if you would like to use both at runtime.
But others seem to suggest you can just "use" two databases in your query:
$sql = "SELECT * FROM dbname.tablename";
$sql = "SELECT * FROM anotherdbname.anothertablename"
I tried preforming a SELECT command on another database besides the one explicitly defined in my PDO connection function. I got this:
Fatal error: Uncaught exception 'PDOException' with message
'SQLSTATE[42000]: Syntax error or access violation: 1142 SELECT
command denied to user 'dbusername'#'localhost' for table
'table_name'
I made sure to add the user to both databases and grant full privileges.
Is a query that uses two databases in the same connection possible? Or do you have to setup two different objects?
"a PDO connection with two databases" (singular form) is a misnomer, because by definition a PDO connection is a single connection to a single data store. If you want two connections, you will need to instantiate two instances.
Turns out preforming a query across two databases is possible with a single PDO connection. Even though one database is defined in my PDO initiation, I still have access to another database.
The solution is to make both databases have the same credentials.
function db_connect(){
$host = 'localhost';
$port = 3306; // This is the default port for MySQL
$database = 'db1';
$username = 'user';
$password = 'pass';
$dsn = "mysql:host=$host;port=$port;dbname=$database";
$db = new PDO($dsn, $username, $password);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $db;
}
$db=db_connect();
$statement = $db->prepare("SELECT * FROM db2.table LIMIT 1");
$statement->execute();
$x=$statement->fetchObject();
var_dump($x); //A full row from the table was the output.
I made sure to add the user to both databases and grant full privileges.
The error message is quite unambiguous. Reading this, I wouldn't be so sure.
Anyway, to answer the title question:
Why not to just run this simple query from the console?
INSERT INTO db2.table SELECT * FROM db1.table;
It will not only transfer your data but also will prove if your users have sufficient rights or not.
If not - you have to really make sure that.

Getting the MySQLi error in class extension

I've got a custom database class which extends the MySQLi class.
It connects to the database using parent in the __construct method.
Below is the portion of the query if the query is not successful, how do I return the error from the server?
$query = parent::query($querystr, $resultmode);
if (!$query) {
$error = str_replace(
'You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use',
'Syntax Error',
mysqli_error(self::getInstance()));
\core\debug::sqlerrorlog($error);
} else {
\core\debug::sqlSuccess();
}
According to docs, you just need to do $this->error.
As I understand, your problem now is that you don't pass a correct intsance of mysqli to mysql_error - maybe self::getInstance() is not doing what it supposed to, but I can't tell from what I see.

problem with doctrine:build-schema

im using symfony with doctrine, and Im trying to generate the schema yml file from a db. I get an this error
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to
your MySQL server version for the right syntax to use near 'group' at line 1. Failing Query: "DESCRIBE group"I have a table named group in my database, and I suspect that this is screwing it up.
Its not access problems as ive checked my db previleges. Any suggestions on what I can do? I have tried the quote-identifier attribute but with no luck : (
Im also struggling to find some good doctrine documentation. i cant seem to find where a list of attributes are, say for a creating a column in the schema.yml file. I tried reaching out to symfony forums but they are not responsive! Any help would be greatly appreciated! Thanks..
As mentioned group is reserved keyword in MySQL, so you need to escape its name. In your project configuration class (/config/ProjectConfiguration.class.php) configure Doctrine Manager to use quotes:
class ProjectConfiguration extends sfProjectConfiguration {
public function setup() {
//...
}
public function configureDoctrine(Doctrine_Manager $manager) {
$manager->setAttribute(Doctrine_Core::ATTR_QUOTE_IDENTIFIER, true);
}
}
Assuming you're using up-to-date MySQL, "group" is a reserved word:
http://dev.mysql.com/doc/refman/5.5/en/reserved-words.html

Categories