How can I set connection for Query builder in yii2? - yii2

I want to use QueryBuilder:
$rows = (new \yii\db\Query())
->select('id, name')
->from('user')
->limit(10)
->all();
with non-default connection:
\Yii::$app->get('db_mysql')
How can I do this properly?

Use:
$rows = (new \yii\db\Query())
->select('id, name')
->from('user')
->limit(10)
->all(\Yii::$app->db_mysql);
Of course, you have to set db_mysql component in your config
Doc:
/**
* Executes the query and returns all results as an array.
* #param Connection $db the database connection used to generate the SQL statement.
* If this parameter is not given, the `db` application component will be used.
* #return array the query results. If the query results in nothing, an empty array will be returned.
*/
public function all($db = null)
{
$rows = $this->createCommand($db)->queryAll();
return $this->populate($rows);
}

In your model create method
/**
* #return \yii\db\Connection the database connection used by this AR class.
*/
public static function getDb()
{
return Yii::$app->get('db_mysql');
}
after that
$rows = (new \yii\db\Query())
->select('id, name')
->from('user')
->limit(10)
->all(YourModel::getDb());
or
$rows = (new \yii\db\Query())
->select('id, name')
->from('user')
->limit(10)
->all(static::getDb());
in YourModel context

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']);
}

Yii 2 - How to set connection in DB Query for multi database

How to set db connection in yii-db-query?
I have a 3 database connection:
db, db2 and db3
When I used this default Query:
$query = (new \yii\db\Query())
->select('*')
->from('trans_journal')
->all();
It will return an error. The trans_journal is not found, because the trans_journal is from the db2 connection.
And when I used this Query:
$query = (new \yii\db\Query())
->select('*')
->from('trans_journal')
->all(\Yii::$app->db2);
The query will be successfully generated but the problem is it will return an array.
Is there another way to solved this?
if you are using an active record model, in your model you can redefine properly the getDB function for each model:
// Model1
public function getDb() {
return Yii::$app->db1;
}
//Model 2
public function getDb() {
return Yii::$app->db2;
}
If you are using command you can set the db in use just in createCommand call
// To get from db1
Yii::$app->db1->createCommand(
(new \yii\db\Query)->select('col1, col2, ... ')->
from('your_table_db1'))->queryAll();
// To get from db2
Yii::$app->db2->createCommand(
(new \yii\db\Query)->select('col1, col2, ... ')->
from('your_table_db2')->queryAll();
The all() method executes the query and returns all results as an array.
You can iterate over the result for get each model eg:
$results = Yii::$app->db1->createCommand(
(new \yii\db\Query)->select('col1, col2, ... ')->
from('your_table_db1'))->queryAll();
foreach($results as $key => $value ){
echo $value->col1;
// or $value['col1];
}
$query = (new \yii\db\Query())
->select('*')
->from('trans_journal')
->all();
$dataProvider = new ActiveDataProvider([
'db' => Yii::$app->get('db2'),
'query' => $query,
]);
$models = $dataProvider->getModels();

How can I return a query object in Yii2?

How can I return all results of yii\db\Query as an object from a query like this one?
$query = new Query;
$query->select('id, name')
->from('user')
->limit(10);
$rows = $query->all();
Try this way
use yii\db\Query;
$query = new Query;
// compose the query
$query->select('id, name')
->from('user')
->limit(10);
// build and execute the query
$rows = $query->all();
// accessing the value
foreach ($rows as $row){
echo $row['name'];
}
for accessing via $row->name;
try with
use common\models\User; // or you app or backend depend where you have models
$rows = User::find()->limit(10)->all();
foreach ($rows as $row){
echo $row->nome;
}

How to pass params for Vend Api?

I am trying to use VEND API but I have no clue how to pass parameters for doing various things. I found a set of codes in the API doc but can't get through it. Below is what I been up to.
<?php
/**
*
* A class made for utility methods around Vend's API
*
*
*/
class VendApiUtils {
/**
* A simple static method to call Vend API urls
*
* #param string $url
* #param string $username
* #param string $password
* #param array $params <OPTIONAL>
*/
public static function requestVendApiUrl($url, $username, $password, $params = array())
{
// is cURL installed?
if (!function_exists('curl_init')) {
throw new Exception('CURL is not installed!');
}
// Create a new cURL instance
$ch = curl_init();
$opts = array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => array('data' => json_encode($params)),
CURLOPT_TIMEOUT => 120,
CURLOPT_FAILONERROR => 1,
CURLOPT_HTTPAUTH => CURLAUTH_ANY,
CURLOPT_USERPWD => "$username:$password"
);
// Assign the cURL options
curl_setopt_array($ch, $opts);
// Get the response
$response = curl_exec($ch);
print_r($response);
// Close cURL
curl_close($ch);
// Execute the request & get the response
echo $response;
}
}
$your_domain='https://mydomain.vendhq.com';
$your_username='myuser';
$your_password='mypass';
$params = array('GET'=>'/api/stock_movements');
$response = VendApiUtils::requestVendApiUrl($your_domain, $your_username,$your_password, $params);
//echo $response;
?>
Any Help would be highly appreicated.
Regards,
Abnab
I'm not sure why you think the URL needs to go into the $params array; that looks to me like the place for, well, params. I think the function is intended to be used more like this:
// Fixed parts, same for any request
$domain='https://mydomain.vendhq.com';
$username='myuser';
$password='mypass';
// Variable parts, depending on what you want to do
$url = '/api/stock_movements';
$params = array('some_key' => 'some_value');
$response = VendApiUtils::requestVendApiUrl($domain . $url, $username, $password, $params);
Please check pyvend client library.

write custom query with zend framework 2

I want to perform a custom query in zf2. Now I have a Album controller and AlbumTable. Inside AlbumTable, I want to perform an join operation. But I am unable to do this.Please give me some suggation.
below my code:
namespace WebApp\Table;
use Zend\Db\TableGateway\TableGateway;
use Zend\Db\Sql\Sql;
new Zend\Db\Adapter\Adapter;
class UserTable
{
protected $tableGateway;
public function __construct(TableGateway $tableGateway)
{
$this->tableGateway = $tableGateway;
}
public function searchUser($search)
{
$search = "mehedi";
$adapter = new Adapter();
$sql = new Sql($adapter);
$select = $sql->select();
$select->from('foo');
$select->join('profiles', 'user.user_id = profiles.ownerId', array('name'));
$select->where(array('id' => 2));
$statement = $sql->prepareStatementForSqlObject($select);
$results = $statement->execute();
return $results;
}
}
The issue is you are trying to instantiate your Adapter with no parameters, when it requires at least a driver :
$adapter = new Adapter(); // Bad
$adapter = new Adapter($driver); // ..
You should use the ServiceManager to get your Adapter, did you start with the Skeleton Application?
It should have already been injected into the TableGateway for you..
$adapter = $this->getAdapter();
An example of instantiating an Adapter:
$config = $serviceLocator->get('Config');
$adapter = new Adapter($config['db']);
where you specify your setup inside your config, local.php will do:
return array(
/**
* Database Config
*/
'db' => array(
'driver' => 'pdo',
'dsn' => 'mysql:dbname=dbname;host=localhost',
'username' => 'root',
'password' => 'password',
),
I got some solution of this problem with helping all of here.
$adapter = $this->tableGateway->getAdapter();
/* $adapter variable is used to fetch Adapter
configuration from serivce manager. */
$sql = new Sql($adapter);
$select = $sql->select();
$select->from('foo');
$select->join('profile', 'foo.skillId = profile.id', array('name'));
$statement = $sql->prepareStatementForSqlObject($select);
$results = $statement->execute();
/* if you want you can see your
desired output in here. */
foreach ($results as $person) {
echo "<pre>";
print_r($person);
}
return $results;
It's because the join method expects an array for the join table. Also I personally would prefix the tables in the query, something like this:-
$search = "mehedi";
$adapter = new Adapter();
$sql = new Sql($adapter);
$select = $sql->select();
// PREFIXED THE foo table f
$select->from(array('f' =>'foo'));
// PREFIXED THE profiles table p
$select->join(array('p' => 'profiles'), 'user.user_id = profiles.ownerId', array('name'));
$select->where(array('id' => 2));
$statement = $sql->prepareStatementForSqlObject($select);
$results = $statement->execute();
return $results;