Saving data to a different database table using Cakephp model::save() - cakephp

I am a newbie to cakephp and could really use some help and suggestions!
the application I am working with currently interacts with two databases, both databases have more or less a similar schema and table structure, I have to save some information in both databases, so i have this table say "employee_information" in both databases, both tables have a set of common fields (first_name, last_name, birthday, gender etc) and some other fields specific to that database.
now i have to save some information into the other database using cakephp model::save() method, previously I was normally switching data source and would use sql INSERT to do this and it was working fine, but now i really would like using cakephp conventional methods to do this, reason is that i think i am missing a great deal by not using cake's own methods ( data sanitizing in my case)
i had tried switching data source and using model::save(), the method did not work, though it did not log any errors, but also did not add any record into the database.
// using following snippet in the model to save.
$this->setDataSource('secondary_database');
$this->save($this->data);
$this->setDataSource('primary_database');
Any ideas or suggestions would be highly appreciated!
Thanks!

You're almost there, but you need to setup two db configs and select them with useDbConfig
For example:
$this->User->save($this->data); //Saves data to default (first) database
$this->User->useDbConfig('second'); //Selects second database for next uses
$this->User->save($this->data); //Saves data to second database too
//$this->User->useDbConfig('default'); //Not needed unless you want to do staff with the default database again later in the same code.
But if I'd need to save different fields in each DB, then I'd go with different models.

Setting custom table for the controller after switching data source worked for me. (http://api.cakephp.org/1.3/class-Model.html#_setSource)
$this->User->setDataSource('secondary_database');
$this->User->setSource('secondary_database_table');
$this->User->save($this->data,array(
'validate' => true,
'fieldList' => $fieldList // specific fields that needs to be updated.
));

Related

How does SQLITE DB saves data of multiple tables in a single file?

I am working on a project to create a simplified version of SQLite Database. I got stuck when trying to figure out how does it manages to store data of multiple tables with different schema, in a single file. I suppose it should be using some indexes to map the data of different tables. Can someone shed more light on how its actually done? Thanks.
Edit: I suppose there is already an explanation in the docs, but looking for some easier way to understand it better and faster.
The schema is the list of all entities (tables, views etc) (the database as a whole) rather than a database existing of many schemas on a per entity basis.
Data itself is stored in pages each page being owned by an entity. It is these blocks that are saved.
The default page size is 4k. You will notice that the file size will always be a mutliple of 4K. You could also, with experimentation create a database with some tables, note it's size, then add some data, and if the added data does not require another page, see that the size of the file is the same. This demonstrating how it's all about pages rather than a linear/contiguos stream of data.
It, the schema, is saved in a table called sqlite_master. This table has columns :-
type (the type e.g. table etc),
name (the name given to the entity),
tbl_name (the tale to which the entity applies )
root page (the map to the first page)
sql (the SQL used to generate the entity, if any)
note that another schema, sqlite_temp_master, may also exist if there are temporary tables.
For example :-
Using SELECT * FROM sqlite_master; could result in something like :-
2.6. Storage Of The SQL Database Schema

Database table in Magento does not exist: sales_flat_shipment_grid

We're using Magento 1.4.0.1 and want to use an extension from a 3rd party developer. The extension does not work, because of a join to the table "sales_flat_shipment_grid":
$collection = $model->getCollection()->join('sales/shipment_grid', 'increment_id=shipment', array('order_increment_id'=>'order_increment_id', 'shipping_name' =>'shipping_name'), null,'left');
Unfortunately this table does not exist n our database. So the error "Can't retrieve entity config: sales/shipment_grid" appears. If I comment this part out, the extension is working, but I guess, it does not proper work.
Does anybody know something about this table? There are a backend-option for the catalog to use the "flat table" option, but this is only for the catalog. And the tables already exists, no matter which option is checked.
As it is obvious from table name, this table contains information about shipments and is used in grid on backend. The problem is that this table was created in 1.4.1.1, so you won't find it in your store.
I see 3 ways of solving the problem:
You can create this table and write some script, that will fill it
with necessary data by cron
You can rewrite SQL-query in that 3rd party extension so that it took necessary data from other sources
You can upgrade your Magento at least to 1.4.1.1 (highly recommended)

How to store data's change history?

I need to store data's change histories in database. For example some time some user modify some property of some data. The expected result is we can get the change histories for one data like
Tom changed title to 'Title one;'
James changed name to 'New name'
Steve added new_tag 'tag23'
Based on these change histories we can get all versions for some data.
Any good idea to achieve this? Not limited to traditional relation database.
These are commonly called audit tables. How I generally manage this is using triggers on the database. For every insert/update from a source table the trigger copies the data into another table called the same table name with an _AUDIT appended to it (the naming convention does not matter, it's just what I use). ORACLE provides you with something called journal tables. Using ORACLE designer (or manually) you can achieve the same thing and often developers put a _JN to the end of the journal/audit table. This, however, works the same, with triggers on the source table copying data into the audit table.
EDIT:
I should also note that you can create a new separate schema to manage just your audit tables or you can keep them in your schema with the source tables. I do both, it just depends on the situation.
I wrote an article about various options: http://blog.schauderhaft.de/2009/11/29/versioned-data/
If you are not tied to a relational database, there are things called 'append only' databases (I think), which never change data, but only append new versions. For your case this sounds kind of perfect. Unfortunately I don't know of any implementation.

How to load whole table into a model?

I have a database table and I want to load it to model? Not by specified condition but whole table. How to do it?
models in ATK4 are used to represent data and to abstract the underlying technicalities but not directly hold them.
it is used by MVCGrid, MVCForm and CRUD to know how data is to be presented / laid out to the user's interface.
though models may not hold data, they are used to retrieve it through dsql.
example:
$m = $this->add('Model_UserAccess');
$u = $m->dsql()
->field('usernm')
->field('acclvl')
//->do_getOne(); // return only 1 record
->do_getAll(); // return all records
the use of DSQL or Dynamic SQL is important
to retrieve data from tables and save it back.
I have a very simple script that creates the necessary .php files to copy to /lib/Model.
I did it because was migrating an Access application with tables of 20-30 attributes and was very tedious to create it by hand.
The script it's very very basic, but it's very useful for me.
Here is the link
https://github.com/ajmmartinez/atk4_create_mod
Try
$data = $mymodel->getRows();
This will get all the data from the model and store into the array. Your question is difficult to understand, so I'm not sure how to reply.

can CakePHP automatically create tables from models?

In python::Pylons i'm able to issue a setup-app command and it will look at my Models and issue the appropriate CREATE TABLE or CREATE INDEX ddl for my particular database.
it seems like this would be a feature in CakePHP, but i'm having trouble finding it.
in fact i see this in the manual:
"You can create your database tables as you normally would. When you create your Model classes, they'll automatically map to the tables that you've created."
which leads me to believe it doesn't exist?
No, it's other way around - you can create models, controllers and views by having DB schema. It's more logical to have a DB design schema first.
Check this out
Some of the comments in the accepted answer above lead me to creating this answer. You can technically create new tables on the fly using the YourModel->query() function. I am currently using this in a Behavior I am writing. This works in CakePHP 2.x, pretty sure it works in 1.3 as well.
In the setup function for the Behavior I am checking to see if the table already exists. If it doesn't I create it.
$dataSource = ConnectionManager::getDataSource('your DB');
if(!in_array($tableName, $dataSource->listSources()){
$this->createYourTableFunction();
}
In the createYourTableFunction you create a temporary model to run the YourModel->query() against. And just provide it your SQL instructions. When creating your temporary model just set the table parameter to false so you don't get a missing table error.
$YourModel = new Model(array('table' => false, 'name' => 'YourModel', 'ds' => 'Your DB'));
$YourModel->query('SQL instruction string');

Resources