Can Magento Connect to Another MySQL database? - mysql

I was wondering if it is possible for Magento have a connection to its primary database, as well as another database that does not contain Magento's core information?
For example, I would like to be able to query tables from a WordPress install that is stored on a different database on a different server?
My first instinct was to create a new database connection using mysql_connect, but it does not feel right to do it this way.
Is there a more "proper" way to accomplish this?

here the complete explanation: http://fishpig.co.uk/magento-tutorials/create-an-external-database-connection-in-magento
in short, you need to create a new resource and tell magento to use this resource for your model, ie, in the config.xml, inside <global> tag:
<resources>
<external_db>
<connection>
<host><![CDATA[host]]></host>
<username><![CDATA[username]]></username>
<password><![CDATA[password]]></password>
<dbname><![CDATA[dbname]]></dbname>
<model>mysql4</model>
<type>pdo_mysql</type>
<active>1</active>
</connection>
</external_db>
<yourmodelalias_read>
<connection>
<use>external_db</use>
</connection>
</yourmodelalias_read>
</resources>

If you look in /lib/Varien/Db/Adapter/Mysqli.php you can see that Magento is extending the Zend_Db_Adapter_Mysqli, and in the _connect() function it is checking if the cached copy of the connection exists immediately.
To me it seems unlikely that using the Magento Db Adapter directly will work, as you would have to override this functionality. So, that leaves two options:
Use the Zend DB adapter, which is pretty easy if you have used it before.
Just use PHP's MySQL functions directly. Make sure to use the PDO or MySQLi libraries, not the ext/mysql. The ext/mysql library is getting deprecated and is a pain to use securely.
http://php.net/manual/en/ref.pdo-mysql.php
http://php.net/manual/en/book.mysqli.php
http://framework.zend.com/manual/en/zend.db.html
Edit: Adding Magento Connect Module
http://www.magentocommerce.com/magento-connect/fishpig/extension/3958/fishpig_wordpress_integration
That is a free Magento->Wordpress bridge. It may be worth looking into their source to see what path they took.

In your module etc/config.xml add following code:
<global>
<resources>
<modulename_write>
<connection>
<use>modulename_database</use>
</connection>
</modulename_write>
<modulename_read>
<connection>
<use>modulename_database</use>
</connection>
</modulename_read>
<modulename_setup>
<connection>
<use>core_setup</use>
</connection>
</modulename_setup>
<modulename_database>
<connection>
<host><![CDATA[localhost]]></host>
<username><![CDATA[db_username]]></username>
<password><![CDATA[db_password]]></password>
<dbname><![CDATA[tablename]]></dbname>
<model>mysql4</model>
<type>pdo_mysql</type>
<active>1</active>
</connection>
</modulename_database>
</resources>
</global>
To get data from table using new database:
<?php
$resource = Mage::getSingleton('core/resource');
$conn = $resource->getConnection('modulename_read');
$results = $conn->fetchAll('SELECT * FROM tablename');
echo "<pre>";
print_r($results);
?>

Related

How can we use solr with both MongoDB and MySQL?

I want to use Solr with MongoDB and MySQL together and need to combine in single core.
For example, I have a MongoDB collection which has depends on MySQL's one table,
I tried both with separate Solr core it's working fine but i want it in single core, i don't know its possible or not, if its possible then how we can use?
Updated
Here my DIHs: (Data import Handler)
- Solr with MySQL
<dataConfig>
<dataSource
name="MySQl"
type="JdbcDataSource"
driver="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost/test"
user="root" password="root"
batchSize="-1"/>
<document>
<entity
query="select * from master_table"
name="master">
</entity>
</document>
</dataConfig>
- Solr with MongoDB
<dataConfig>
<dataSource
name="MyMongo"
type="MongoDataSource"
database="test" />
<document>
<entity
processor="MongoEntityProcessor"
query=""
collection="MarketCity"
datasource="MyMongo"
transformer="MongoMapperTransformer"
name="sample_entity">
<field column="_id" name="id" mongoField="_id" />
<field column="keyName" name="keyName" mongoField="keyName"/>
</entity>
</document>
</dataConfig>
So i want to do with the single core.
You can read the data from Mysql and MongoDB. Merge this records in single record and the index the same into solr.
To get the data from MySql, use any programming language and fetch the data.
For example you can use Java and fetch the data from mysql.
Apply the same logic to MongoDB. Get all the required records from mongoDB using Java.
Now By using the SolrJ apis create the solrDocument. Read more about the SolrDOcument and other apis here
Once your create the instance of SolrDocument then add the data that you fetched from Mysql and MongoDB into it using the below method.
addField(String name, Object value)
This will add a field to the document.
You can prepare the document something like this.
SolrInputDocument document = new SolrInputDocument();
document.addField("id", "123456");
document.addField("name", "Kevin Ross");
document.addField("price", "100.00");
solr.add(document);
solr.commit();
Get a solr instance of HttpSolrClient.
Once the SolrDocument is ready, index it to solr.

jooq specify database runtime

I have the exact same database definition for multiple databases ( and database servers ). How do I tell Jooq to use the same database as the "Connection" I created to connect to the DB?
Example ( for MySQL ):
jdbc:mysql://localhost:3306/tsm - my development DB ( tsm ), used to generate code
jdbc:mysql://RemoteAmazonDBHost:3306/customer1 - one of my customers
jdbc:mysql://RemoteAmazonDBHost:3306/customer2 - Another customer
All 3 databases have the same definition, the same tables, indexes, etc. The TSM one is the standard our application uses.
Maybe I should be using DSL.using( Connection, Setting ) instead of DSL.using(Connection)? Is that what the manual is implying here?
If I only have one "Input" schema, do I have to specify it? In other words, can I do something like this:
Settings settings = new Settings()
.withRenderMapping(new RenderMapping()
.withSchemata(
new MappedSchema().withOutput(
databaseInfo.getProperties().getProperty("database.db"))));
Or do I have to do something like this:
Settings settings = new Settings()
.withRenderMapping(new RenderMapping()
.withSchemata(
new MappedSchema().withInput("TSM")
.withOutput(databaseInfo.getProperties().getProperty("database.db"))));
I'm assuming you're using code generation. In that case, it might be the easiest to not generate the schema at all but use <outputSchemaToDefault> in the code generation configuration, e.g.
<configuration>
<generator>
<database>
<inputSchema>your_codegen_input_schema_here</inputSchema>
<outputSchemaToDefault>true</outputSchemaToDefault>
</database>
</generator>
</configuration>
See the manual for details: https://www.jooq.org/doc/latest/manual/code-generation/codegen-advanced/codegen-config-database/codegen-database-catalog-and-schema-mapping/
If you want to keep your generated code with schema qualification and map things at runtime, then your second attempt seems correct. Pass this to your Configuration (i.e. the DSL.using() call):
Settings settings = new Settings()
.withRenderMapping(new RenderMapping()
.withSchemata(new MappedSchema()
.withInput("TSM")
.withOutput(databaseInfo.getProperties().getProperty("database.db"))));
More details can be found here: https://www.jooq.org/doc/latest/manual/sql-building/dsl-context/custom-settings/settings-render-mapping

WSO2 MySQL Adaptor Sytax Error

I am trying to create an event formatter for MySql in WSO2 but am hitting a problem. It appears to be linked to the use of "Composite Key Columns". The error I am getting is:
ERROR - {MysqlEventAdaptorType}
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: 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 'Window = '15'' at line 1
This only happens if I use a two or more keys in the formatter:
<eventFormatter name="GenericAccountSQLFormatter" statistics="enable"
trace="enable" xmlns="http://wso2.org/carbon/eventformatter">
<from streamName="GenericAccountMeasureStream" version="1.0.0"/>
<mapping customMapping="disable" type="map"/>
<to eventAdaptorName="APCSQLOut" eventAdaptorType="mysql">
<property name="table.name">AccountStats</property>
<property name="update.keys">AccountId,Window</property>
<property name="execution.mode">insert-or-update</property>
</to>
</eventFormatter>
Removing either of the keys (AccountId, Window) then the formatter will send data to MySQL.
Can anyone help?
This is a bug and happens when existing events are sent to a MySQL adaptor with composite keys. Created a jira to track this and the source patch is also available there.
If you don't want to create/apply a patch, then as a quick workaround for now - you can output a composite key from CEP query by concatenating the two attributes and use that as the key in formatter.
UPDATE
The source patch with the fix and build instructions are now available in the jira here. Once built, you need to apply it as a patch to CEP. To apply it as a patch, create a directory named patch0xyz ( xyz are digits as in patch0135, also make xyz > 100) in <CEP>/repository/components/patches and then place the jar inside it. Then you need to rename the jar as org.wso2.carbon.event.output.adaptor.mysql_1.0.1.jar. Then restart the server.

MySQL to MySQL data copy in scriptella

I m trying to use a scriptella script to transfer some data to data in one server to another.
The script looks something like this
<!DOCTYPE etl SYSTEM "http://scriptella.javaforge.com/dtd/etl.dtd">
<etl>
<description>
test script
</description>
<properties>
<include href="../config/kpoint-etl.properties"/>
</properties>
<connection id="in" driver="${driver}" url="${url}" user="${user}" password="${password}">
</connection>
<connection id="out" driver="${driver}" url="${url2}" user="${user}" password="${password}">
</connection>
<query connection-id="in">
SELECT owner_name, owner_domain, DATE(time_last_update)
as pdate, count(*) as avg from kapsule where DATE(time_last_update)="2013-06-19" group by owner_name;
<script connection-id="out">
UPDATE test SET username=?owner_name, domain=?owner_domain, frequency=?avg, rdate=?pdate;
</script>
</query>
</etl>
the 'in' connection id seems to be working fine, but on connection to the second server it shows the following error.
JDBC provider exception: Unable to obtain
connection for URL jdbc:/mysql://localhost:3306/leopard
Error codes: [08001, 0]
Driver exception: java.sql.SQLException: No suitable
driver found for jdbc:/mysql://localhost:3306/leopard
The properties file is something like this
driver=mysql
url=jdbc:mysql://192.168.8.72:3306/leopard
user=leopard
password=user12
url2=jdbc:/mysql://localhost:3306/leopard
Any help will be appreciated. Thank You.
P.s. Do ask for any doubts regarding the question.
You have an extra slash in the second url jdbc:/mysql. Try removing it.

How to execute large sql query in magento?

I want to store huge content in db and my sample text is 16129 characters in length when i tried to execute this query it is showing "error:The requested URL could not be retrieved" in firefox and "no-data received" in chrome.
Moreover I use LONGTEXT as datatype for text in DB.
I also tried to execute the query directly in phpmyadmin it is working correctly.
The code is shown below.
public function _getConnection($type = 'core_write') {
return Mage::getSingleton('core/resource')->getConnection($type);
}
public function testdbAction(){
$db = $this->_getConnection();
$current_time=now();
$text="The European languages are members of the same family...... ...Europe uses the same vocabulary. The ";//text is 16129 characters in length
$sql = "INSERT into test(`usercontent_id`,`app_id`,`module_id`,`customer_id`,`content`,`created_time`,`updated_time`,`item_id`,`index_id`,`position_id`) VALUES (NULL, 15, 9,2,'" .$text. "','" . $current_time . "','" . $current_time . "',1003,5,4)";
$db->query($sql);
}
How do i handle this? any suggestions or help..
Try using $db->exec($sql) instead of $db->query($sql)
For manipulating with database structure and data Magento has a dedicated place. It is called install / upgrade scripts. It was made to keep track of modules version for easy updates. So you should use a script to add new data.
Here's an example.
config.xml of your module:
<modules>
<My_Module>
<version>0.0.1</version>
</My_Module>
</modules>
<global>
<resources>
<my_module_setup>
<setup>
<module>My_Module</module>
<class>Mage_Core_Model_Resource_Setup</class>
</setup>
</my_module_setup>
</resources>
</global>
Now, you need to create following file:
My_Module/sql/my_module_setup/install-0.0.1.php
Now, depending on your Magento version, file would need to have a different name. If you're using Magento CE 1.4 or lower (EE 1.8) then you should name it mysql4-install-0.0.1.php.
This script will be launched at next website request. Class Mage_Core_Model_Resource_Setup will execute code inside install-0.0.1.php. From within the install script you will have access to the Setup class by using $this object;
So now, you can write in script following code:
$this->startSetup();
$text = <<<TEXT
YOUR LONG TEXT GOES HERE
TEXT;
$this->getConnection()
->insert(
$this->getTable('test'),
array(
'usercontent_id' => null,
'app_id' => 15,
'content' => $text,
//other fields in the same fashion
)
);
$this->endSetup();
And that's it. It's a clean and appropriate way of adding custom data to the database in Magento.
If you want to save a user input on a regular basis using forms, then I recommend creating w model, resource model and collection, define entities in config.xml. For more information please refer to Alan Storm's articles, like this one.
I hope that I understood your question correctly.