How to optimize THINKPHP's support for ORACLE databases

Source: Internet
Author: User
Tags bind commit rollback

 

Thinkphp's support for Oracle is simply weak. It only performs basic operations, and even transactions are not supported. Modify DbOracle. class. php manually today to make it easier to use.


First, insert. There should be no problem with the original insert, but in actual projects, it is more necessary to update an existing record when inserting. Therefore, we use merge into in Oracle to achieve this.

Public function insert ($ data, $ options = array (), $ replace = false)
{
If (! $ Replace ){
Return parent: insert ($ data, $ options, $ replace );
}
 
$ Values = $ fields = array ();
$ This-> model = $ options ['model'];
 
$ SQL _merge = 'merge into'. $ this-> parseTable ($ options ['table']).
'Using (select 1 from dual )'.
'On ('. $ this-> parseValue ($ data [$ options ['Marge _ key']). 'is not null and '. $ this-> parseValue ($ data [$ options ['Marge _ key']). '= '. $ options ['Marge _ key']. ')';
 
// Insert
Foreach ($ data as $ key => $ val ){
// When the primary key value is null, the primary key is not inserted.
If ($ this-> parseKey ($ key) =$ this-> parseKey ($ options ['Marge _ key'])
& Amp; $ val = null
){
 
} Elseif (is_array ($ val) & 'Exp '= $ val [0]) {
$ Fields [] = $ this-> parseKey ($ key );
$ Values [] = $ val [1];
} Elseif (is_scalar ($ val) | is_null ($ val) {// filter non-standard data
$ Fields [] = $ this-> parseKey ($ key );
If (C ('Db _ bind_param') & 0! = Strpos ($ val ,':')){
$ Name = md5 ($ key );
$ Values [] = ':'. $ name;
$ This-> bindParam ($ name, $ val );
} Else {
$ Values [] = $ this-> parseValue ($ val );
}
}
}
$ SQL _insert = 'Insert ('. implode (', ', $ fields).') VALUES ('. implode (', ', $ values ).')';
 
// Update
If (isset ($ data [$ this-> parseKey ($ options ['Marge _ key'])
| $ Data [$ this-> parseKey ($ options ['Marge _ key'])] = null
){
Unset ($ data [$ this-> parseKey ($ options ['Marge _ key']);
}
$ SQL _update = 'Update'
. $ This-> parseSet ($ data)
. $ This-> parseWhere (! Empty ($ options ['where'])? $ Options ['where']: '')
. $ This-> parseOrder (! Empty ($ options ['order'])? $ Options ['order']: '')
. $ This-> parseLimit (! Empty ($ options ['limit'])? $ Options ['limit']: '');
 
$ SQL = $ SQL _merge. 'When matched then '. $ SQL _update. 'When not matched then'. $ SQL _insert;
Return $ this-> execute ($ SQL, $ this-> parseBind (! Empty ($ options ['bind'])? $ Options ['bind']: array ()));
}
Not supporting transactions is another issue when Thinkphp connects to Oracle. The framework author seems to have adapted, but it should have not been tested, leaving a bunch of bugs. DbOracle. class. php already has startTrans, commit, rollback, etc. Just make a slight modification.

Thinkphp eventually collects all database operations to query or execute, but these two functions put a sentence $ this-> mode = OCI_COMMIT_ON_SUCCESS; the transaction is killed in a living way, so, comment out the sentence in the two functions first.

Then, it is amazing to find that the mode is not passed in when calling oci_execute in execute! How hard it was to change the mode, and how hard it was to add oci_execute ($ stmt, $ this-> mode ).

The next step is to make the transaction take effect. Add the mode modification to several switch functions of the transaction. In startTrans (), set the mode to OCI_DEFAULT, and change the mode back to OCI_COMMIT_ON_SUCCESS in commit and rollback. These three functions are like this:

/**
* Start the transaction
* @ Access public
* @ Return void
*/
Public function startTrans (){
$ This-> initConnect (true );
If (! $ This-> _ linkID) return false;
// Data rollback support
If ($ this-> transTimes = 0 ){
$ This-> mode = OCI_DEFAULT;
    }
$ This-> transTimes ++;
Return;
    }
    
/**
* Used for querying and submitting under the non-automatic submission status
* @ Access public
* @ Return boolen
*/
Public function commit (){
If ($ this-> transTimes> 0 ){
$ Result = oci_commit ($ this-> _ linkID );
If (! $ Result ){
$ This-> error ();
Return false;
    }
$ This-> mode = OCI_COMMIT_ON_SUCCESS; // Chen Xuanyi 2014.11.09
$ This-> transTimes = 0;
    }
Return true;
    }
    
/**
* Transaction rollback
* @ Access public
* @ Return boolen
*/
Public function rollback (){
If ($ this-> transTimes> 0 ){
$ Result = oci_rollback ($ this-> _ linkID );
If (! $ Result ){
$ This-> error ();
Return false;
    }
$ This-> mode = OCI_COMMIT_ON_SUCCESS; // Chen Xuanyi 2014.11.09
$ This-> transTimes = 0;
    }
Return true;
    }

Another headache is the date type conversion. I am still looking for a convenient way to solve this problem. I will try again later.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.