I'm refactoring an existing application which is using old methods to connect and interact with a mysql database like mysql_connect() and mysql_fetch_array which had code like:
Update
The only output Im getting on the page is the below, which are empty arrays.
Array ( [initial] => Array ( ) [additional] => Array ( ) )
Final update This was an issue with the root user not having access to %. I was getting an error like: The user specified as a definer ('root'#'%') does not exist on output this is fixed by running the command:
grant all on *.* to 'root'#'%' identified by 'password' with grant option;
The reason for converting was using the originally coded use of mysql_connect() (not by me) does not work (as far as I know) with mysql when you have remote connections turned off (which I do).
Why isn't my new code outputting anything? The original code above works in development env. where remote connections is turned off, but not in production.
Thank you.
Your class has a missing closing bracket } at the end.
You do not select database
Why do you create $this->dbConn everywhere, you defined it in your constructor.
Where is your $this->dbConn->query defined? $this->dbConn is a resource of connection.
NOTE
Add error_reporting(E_ALL); and ini_set('display_errors', 1); to catch your errors.
Related
I need to modify the existing 'default' connection.
I tried to write it like this:-
ConnectionManager::config('default',$consoptions);
It gives an error telling me that we cannot reconfigure existing key "default".
Is there any way to achieve what I want?
The example shown in the CakePHP Cookbook is wrong and causes the error
Cannot reconfigure existing key "default"
You actually need to drop the default database connection configuration before replacing it with a new one.
In addition, the ConnectionManager::config() methos is deprecated in favour of ConnectionManager::setConfig()
This is a working example that modifies the default database connection:
use Cake\Datasource\ConnectionManager;
$dsn = 'mysql://root:password#localhost/my_database';
ConnectionManager::drop('default');
ConnectionManager::config('default', ['url' => $dsn]);
It gives an error telling me that we cannot reconfigure existing key "default" Is there any way to achieve what I want?
Drop the config then configure it again.
Spend some time checking the API, it's almost all there.
PHP's Mongo driver lacks a renameCommand function. There is reference to do this through the admin database. But it seems more recent versions of the Mongo driver don't let you just "use" the admin database if do don't have login privileges on that database. So this method no longer works. I've also read this doesn't work in sharded environments although this isn't a concern for me currently.
The other suggestion people seem to have is to iterate through the "from" collection and insert into the "to" collection. With the proper WriteConcern (fire and forget) this could be fairly fast. But it still means pulling down each record over the network into the PHP process and then uploading it back over the network back into the database.
I ideally want a way to do it all server-side. Sort of like an INSERT INTO ... SELECT ... in SQL. This way it is fast, network efficient and a low load on PHP.
I have just tested this, it works as designed ( http://docs.mongodb.org/manual/reference/command/renameCollection/ ):
$mongo->admin->command(array('renameCollection'=>'ns.user','to'=>'ns.e'));
That is how you rename an unsharded collection. One problem with MR is that it will change the shape of the output from the original collection. As such it is not very good at copying a collection. You would be better off copying it manually if your collection is sharded.
As an added note I upgraded to 1.4.2 (which for some reason comes out from the pecl channel into phpinfo() as 1.4.3dev :S) and it still works.
Updates:
Removed my old map/reduce method since I found out (and Sammaye pointed out) that this changes the structure
Made my exec version secondary since I found out how to do it with renameCollection.
I believe I have found a solution. It appears some versions of the PHP driver will auth against the admin database even though it doesn't need to. But there is a workaround where the authSource connection param is used to change this behavior so it doesn't auth against the admin database but instead the database of your choice. So now my renameCollection function is just a wrapper around the renameCollection command again.
The key is to add authSource when connecting. In the below code $_ENV['MONGO_URI'] holds my connection string and default_database_name() returns the name of the database I want to auth against.
$class = 'MongoClient';
if( !class_exists($class) ) $class = 'Mongo';
$db_server = new $class($_ENV['MONGO_URI'].'?authSource='.default_database_name());
Here is my older version that used eval which should also work although some environments don't allow you to eval (MongoLab gives you a crippled setup unless you have a dedicated system). But if you are running in a sharded environment this seems like a reasonable solution.
function renameCollection($old_name, $new_name) {
db()->$new_name->drop();
$copy = "function() {db.$old_name.find().forEach(function(d) {db.$new_name.insert(d)})}";
db()->execute($copy);
db()->$old_name->drop();
}
you can use this. "dropTarget" flag is true then delete exist database.
$mongo = new MongoClient('_MONGODB_HOST_URL_');
$query = array("renameCollection" => "Database.OldName", "to" => "Database.NewName", "dropTarget" => "true");
$mongo->admin->command($query);
So I'm confident that the stored procedure works, I've tested it in SQL Server Management Studio just fine and it runs in other service instances. The query used to run this SP follows;
exec sp_getAgentCommissionDetails_v3 201000023762230, 5
So it runs fine on SSMS and under the old MSSQL driver. But I run the query with SQLSRV like so;
function mssql_query($string, $linkID = null, $batch = 0) {
if (!$linkID) {
global $dbhandle;
$linkID = $dbhandle;
}
// SQLSRV_CURSOR_KEYSET ensures mssql_num_rows() works in most cases. Default scrollablility does not support this.
return sqlsrv_query($linkID, $string, array(), array("Scrollable" => SQLSRV_CURSOR_KEYSET));
}
The function is named mssql_query because we're updating an old system from MSSQL to SQLSRV, but we're working with an extremely messy old system. So rather than trying to refactor it we're overwriting the MSSQL_query function (having disabled the mssql extension) with one that uses SQLSRV.
$dbhandle is our SQLSRV connection resource. Other queries run just fine using this method.
So my question- is there any reason the query to run a stored procedure would not run under this SQLSRV function?
Couple notes on my troubleshooting;
I'm aware SQLSRV and PDO have a specific method to run stored procedures. Using that is not an option due to the massive codebase that uses the method above in various places and because we haven't got the man hours to refactor every page.
I pulled up SQLSRV_errors() and it returned 'Executing SQL directly; no cursor'. After a bit of research this seems to be a bug in the driver that returns this generic error message instead of a more specific useful one, so it can mean very many things.
There are no cursors or loops involved in the stored procedure.
Found a solution to this. SQLSRV seems to by default treat warnings as errors. Fixed this with a config change in the connection file;
sqlsrv_configure("WarningsReturnAsErrors",0);
It now runs fine.
Using php driver 1.3.2 and mongodb 2.2, I am trying to use readPreference to direct an aggregate query to one of the secondaries in my replica set. Seems whatever I try, the aggregate query is executed on the primary server.
Basic example:
$db = new \MongoClient('rs1.example:27017,rs2.example:27017,rs3.example:27017', array('replicaSet' => 'myRs') );
$db->setReadPreference( \MongoClient::RP_SECONDARY );
$results = $db->tracking->sessions->aggregate( array( ... ) );
I enabled MongoLog and got the following results:
The aggregate method shows: REPLSET INFO: - connection: type: PRIMARY
If I use find instead, it shows: REPLSET INFO: - connection: type: SECONDARY
Is this a bug with the php driver? Anyone else run into this? Thought I would toss it on SO before adding it as a bug in their Jira.
All command queries through the PHP driver are currently directed to primary servers. We have several old tickets related to this, originating with requests to direct count commands to secondaries, but it was a non-trivial change that requiring checking the command against a whitelist to ensure it is read-only. The current ticket tracking this fix is PHP-535, which I linked to the issue you opened, PHP-662.
If you need an immediate work-around, you can call find() on the $cmd collection directly, passing the same $command array argument that you'd typically pass to MongoDB::command() as the argument to find(). Kristina documented this solution in this JIRA comment, and although she used slaveOkay() in that example, it should also work with read preferences.
Using the example from the manual:
$mongo = new Mongo("mongodb://sf2.example.com,ny1.example.com", array("replicaSet" => "myReplSet"));
When I check $mongo, it says it is indeed connected. I thought I could then call $mongo->isMaster() to get replica set details, but that doesn't work. Is that not a proper way of doing this?
isMaster isn't a PHP function (see http://www.php.net/manual/en/class.mongo.php for a list of functions available in the Mongo class). You can do:
$result = $mongo->myDb->command(array("isMaster" => 1));
This runs the isMaster command on the myDb database (it doesn't matter what db you run it on).