Modifying records on Yii2 Mater Slave Steup - yii2

In our commercial app, we are using master/slave feature in database configuration and running a MSSQL(business requirement) db as the master and MySQL db as a slave. We want to do read requests from the slave(MySQL) and write requests to the master(MSSQL). We have configured a background job to copy data from master to slave.
I tried to do an update to the master and it failed since the SQL generated was having MySQL syntax but not the MSSQL syntax. The connection is switching correctly to the master. When I checked update() function in the db/QueryBuilder.php file,
public function update($table, $columns, $condition, &$params)
{
if (($tableSchema = $this->db->getTableSchema($table)) !== null) {
$columnSchemas = $tableSchema->columns;
} else {
$columnSchemas = [];
}
$lines = [];
foreach ($columns as $name => $value) {
if ($value instanceof Expression) {
$lines[] = $this->db->quoteColumnName($name) . '=' . $value->expression;
foreach ($value->params as $n => $v) {
$params[$n] = $v;
}
} else {
$phName = self::PARAM_PREFIX . count($params);
$lines[] = $this->db->quoteColumnName($name) . '=' . $phName;
$params[$phName] = !is_array($value) && isset($columnSchemas[$name]) ? $columnSchemas[$name]->dbTypecast($value) : $value;
}
}
$sql = 'UPDATE ' . $this->db->quoteTableName($table) . ' SET ' . implode(', ', $lines);
$where = $this->buildWhere($condition, $params);
return $where === '' ? $sql : $sql . ' ' . $where;
}
It seems that
$this->db->quoteColumnName($name)
always gets the MySQL format. We need to have it with MSSQL format added in the QueryBuilder class in mssql/QueryBuilder.php file. I'm bit confused on how the schema is selected in this scenario for
$this->db
Please let me know how to fix this issue. Thanks in advance!
Sam

Seems that you are using a single database connection .. could be you need a duoble database connect each of them related to the proper db
eg: db1 for mysql and db2 for mssql
return [
'components' => [
'db1' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=db1mysql_name',
'username' => 'db1username',
'password' => 'db1password',
],
'db2' => [
'class' => 'yii\db\Connection',
'dsn' => 'sqlsrv:Server=your.ip.address.here;Database=db2msssql_name', // change your.ip.address.here with a proper if
'username' => 'db2username',
'password' => 'db2password',
],
],
and then use proper connect to the right db
Yii::$app->db1;
Yii::$app->db2;

Related

From Laravel how to get mysql schema process list when another request executing a large query?

I have tried this code to get current running mysql process for this db and current user but the problem is when another api is called with large runtime query this previouse api block this request.
public function getDBProcess_p(Request $request)
{
$db = env('DB_DATABASE') ?? '';
$username = env('DB_USERNAME') ?? '';
$password = env('DB_PASSWORD') ?? '';
$data = DB::table('INFORMATION_SCHEMA.PROCESSLIST')
->where(
[
'DB' => $db,
'USER' => $username,
'COMMAND' => 'Execute',
]
)
->paginate(10);
$data = [
'paginator' => getFormattedPaginatedArray($data),
'data' => $data->items(),
];
return $this->set_response($data, 200,'success', ['Process list']);
}

Yii2-user Dektrium - how to hash password

i want to do hash password and check that with database ( password_hash )
How can I do it????
$username = $auth['username'];
my password is
$password = $auth['password'];
i want hash that :
$find = \dektrium\user\models\User::findOne(['username' => $username, 'password_hash' => $password]);
You could generate the $hash using
$hash = Yii::$app->getSecurity()->generatePasswordHash($password);
$find = \dektrium\user\models\User::findOne(['username' => $username,
'password_hash' => $hash]);
Th code belowe is from dektrium/yii2-user/helpers/password.php ( the code for hash function ..of dektrium adn as you see the extensions use the generatePasswordHash and a cost
public static function hash($password)
{
return \Yii::$app->security->generatePasswordHash($password,
\Yii::$app->getModule('user')->cost);
}
default cost = 8
I know quite late to answer this, but for those who are still looking.. I recently encountered this issue and after lots of testing below code worked for me:
$behaviors['authenticator'] = [
'class' => HttpBasicAuth::className(),
'auth' => function ($username, $password) {
$user = \dektrium\user\models\User::findOne(['username' => $username]);
if ($user->validate($password)) {
return $user;
}
return null;
}
];

Yii2 Kartik-V Typeahead Advanced Widget: How to store result in Mysql

Tearing my hair out at this point, hopefully someone can help me out!
I am using the Kartik-V Typeahead Advanced widget with Yii2.
The plugin works, in that the functionality is working perfectly on the page, I search and the results appear in the auto complete list.
Unfortunately, I am unable to store the result in my database. I am seeing an issue on the following line:
->where([ 'name' => $model->name ])//This variable is returning null
Am I trying to store the data incorrectly? I have tried everything I can think of, but I am sure someone here will come up with something better!
See below for the full code.
My controller:
public function actionIndex()
{
$model = new Member();
if ($model->load(Yii::$app->request->post())) {
$test = Test::find()
->where([ 'name' => $model->name ])//This variable is returning null
->one();
$test->updateCounters(['times_used' => 1]);
}
return $this->render('index', [
'model' => $model,
]);
}
/*************
* Initial prefetch of results
*************/
public function actionPrefetchlist() {
$query = new Query;
$query->select('name')
->from('test_table')
->limit(10)
->orderBy('times_used');
$command = $query->createCommand();
$data = $command->queryAll();
$out = [];
foreach ($data as $d) {
$out[] = ['value' => $d['name']];
}
echo Json::encode($out);
}
/*************
* Remote results
*************/
public function actionRemotelist() {
$query = new Query;
$query->select('name')
->from('test_table')
->where('name LIKE "%' . $q .'%"')
->limit(10)
->orderBy('times_used');
$command = $query->createCommand();
$data = $command->queryAll();
$out = [];
foreach ($data as $d) {
$out[] = ['value' => $d['name']];
}
echo Json::encode($out);
}
The view file:
echo $form->field($model, 'name')->label(false)->widget(Typeahead::classname(), [
'name' => 'name',
'options' => ['placeholder' => 'Filter as you type ...'],
'pluginOptions' => ['highlight'=>true],
'dataset' => [
[
'datumTokenizer' => "Bloodhound.tokenizers.obj.whitespace('value')",
'display' => 'value',
'prefetch' => Url::to(['prefetchlist']),
'remote' => [
'url' => Url::to(['remotelist']) . '?q=%QUERY',
'wildcard' => '%QUERY'
]
]
]
]);
you ask here for a new model:
$model = new Member();
so you get a empty model
so the $model->name is empty
if you set the model $model->name='test';
than it will be filled so, fill the model first
So it turns out it was a massive rookie error.
If anyone else stumbles upon something similar, I removed the attribute name from the model's "rules()"
I need an integer in the database but I wanted users to enter in a string (I would then convert it in the controller). Removing it from the rule broke everything.
Hopefully this helps someone else :)

MySQL database table not inserting data

I have a MySQL database table named login which stores user information and login details. The table has been working well (inserting, updating and selecting) but from yesterday,the table is not inserting data from my php codeigniter scripts but its selecting and updating.
Also, when I insert a row manually (in phph Myadmin), its inserting well. The table has only 470 rows and its using InnoDB ingine and its 192KB. What could be the problem? The database is on a shared host. Here is the php code
function insertUser($pfNo, $fName, $mName, $lName, $email, $username, $encPassword, $userType,$preuniYear, $salt, $creationDate){
$data = array(
'pfNo' => $pfNo,
'fName' => $fName,
'mName' => $mName,
'lName' => $lName,
'email' => $email,
'username' => $username,
'password' => $encPassword,
'userType' => $userType,
'year' => $preuniYear
);
$query1 = $this->db->insert('login', $data);
$data = array(
'username' => $pfNo,
'creationDate' => $creationDate
);
$query3 = $this->db->insert('systemdetails', $data);
if ($query1 && $query3) {
return true;
} else {
return false;
}
}`

Insert blob (from mysql) data in varbinary (SQL Server) field with Zend_Db

I have a MySQL table that needs to be synchronized with a SQL Server table. So the data from MySQL moves to SQL Server. It is done by simple SELECT * and INSERT INTO queries. However, I ran into problems with migrating some BLOB data to a varbinary field.
So I have this code:
$db_mysql = new Zend_Db_Adapter_Pdo_Mysql(array(
'host' => '127.0.0.1',
'username' => '<user>',
'password' => '<password>',
'dbname' => '<db>',
'charset' => 'utf8'
));
$db_mssql = new Zend_Db_Adapter_Pdo_Mssql(array(
'pdoType' => 'sqlsrv',
'host' => '<host>',
'username' => '<user>',
'password' => '<password>',
'dbname' => '<db>'
));
$rows = $db_mysql->fetchAll("SELECT Id, Picture FROM Rosters");
foreach ($rows as $row) {
$update_sql = "UPDATE Rosters SET Picture = :picture WHERE Id = :id";
$stmt = new Zend_Db_Statement_Pdo($db_mssql, $update_sql);
$stmt->bindValue(":picture", bin2hex($row['Picture']), Zend_Db::PARAM_LOB);
$stmt->bindValue(":id", $row['Id'], Zend_Db::PARAM_INT);
try {
$stmt->execute();
} catch (Exception $e) {
echo $e->getMessage();
var_dump($e);
die();
}
}
This gives me the incredible not-so-useful error message: PDOException: SQLSTATE[HY000]: General error: 257 General SQL Server error: Check messages from the SQL Server [257] (severity 16) [(null)]
The MySQL Blob field is defined as BLOB with the attribute BINARY, the SQL Server field is defined as (varbinary(max), null). I think it's just a simple mistake, but I can't figure it out. Can anyone help me out with this?
Ok. I found it out on my own, this is the working code:
$db_mysql = new Zend_Db_Adapter_Pdo_Mysql(array(
'host' => '127.0.0.1',
'username' => '<user>',
'password' => '<pass>',
'dbname' => '<db>',
'charset' => 'utf8'
));
$db_mssql = new Zend_Db_Adapter_Pdo_Mssql(array(
'pdoType' => 'odbc',
'host' => '<host>',
'username' => '<user>',
'password' => '<pwd>',
'dbname' => 'Roosters'
));
$rows = $db_mysql->fetchAll("SELECT Id, Picture FROM Rosters");
foreach ($rows as $row) {
$update_sql = "UPDATE Rosters SET Picture = CONVERT(varbinary(max), :picture, 2) WHERE Id = :id";
$stmt = new Zend_Db_Statement_Pdo($db_mssql, $update_sql);
$stmt->bindValue(":picture", bin2hex($row['Picture']));
$stmt->bindValue(":id", $row['Id'], Zend_Db::PARAM_INT);
try {
$stmt->execute();
} catch (Exception $e) {
echo $e->getMessage();
var_dump($e);
die();
}
}
?>