Moodle & Database & php : Data manipulation API ( select, update, insert, delete etc.) + examples

TrablaMoodle & Database & php : Data manipulation API ( select, update, insert, delete etc. ) + examples - Moodle API for work with Database



Solving: 

Overview:

 1.  Before using API
 2.  Getting a single record (select)
 3.  Getting an hashed array of records  (select)
 4.  Getting data as key/value pairs in an associative array  (select)
 5.  Seeing how many records match a given criterion (count)
 6.  Seeing if one record exists (exists)
 7.  Getting a particular field value from one record (select)
 8.  Getting a particular field value from various records (select)
 9.  Setting a particular field in the database (update)
10. Deleting Records (delete)
11. Inserting Records (insert)
12. Updating Records (update)
13. Using Recordsets (select)
14. Delegated transactions
15. SQL compatibility functions
16. Debug fuctions (debug)
17. Special cases (courses)




1.  Before using API:

/// Include global object before using API
global $DB;

The $DB global object is an instance of the moodle_database class, which is defined in moodle_database.php

2.  Getting a single record

o $DB->get_record($table, array $conditions, $fields='*', $strictness=IGNORE_MISSING)
  /// Get a single database record as an object where all the given conditions met.
  /// @param int $strictness IGNORE_MISSING means compatible mode, false returned if record not found, debug message if more found;
  ///                        IGNORE_MULTIPLE means return first, ignore multiple records found(not recommended);
  ///                        MUST_EXIST means throw exception if no record or multiple records found
o $DB->get_record_select($table, $select, array $params=null, $fields='*', $strictness=IGNORE_MISSING)
  /// Get a single database record as an object which match a particular WHERE clause.
o $DB->get_record_sql($sql, array $params=null, $strictness=IGNORE_MISSING)
  /// Get a single database record as an object using a SQL statement.

 3. Getting an hashed array of records

 Each of the following methods return an array of objects. The array is indexed by the first column of the fields returned by the query. Thus to assure consistent data, it appears to be best practice to ensure that your query include an "id column" as the first field. (When developing custom tables, be sure to make id your first column for this reason!)

 o $DB->get_records($table, array $conditions=null, $sort='', $fields='*', $limitfrom=0, $limitnum=0)
  /// Get a number of records as an array of objects where all the given conditions met.
o $DB->get_records_select($table, $select, array $params=null, $sort='', $fields='*', $limitfrom=0, $limitnum=0)
  /// Get a number of records as an array of objects which match a particular WHERE clause.
o $DB->get_records_sql($sql, array $params=null, $limitfrom=0, $limitnum=0)
  /// Get a number of records as an array of objects using a SQL statement.
o $DB->get_records_list($table, $field, array $values, $sort='', $fields='*', $limitfrom='', $limitnum='')
  /// Get a number of records as an array of objects where one field match one list of values.

  4. Getting data as key/value pairs in an associative array

  o $DB->get_records_menu($table, array $conditions=null, $sort='', $fields='*', $limitfrom=0, $limitnum=0)
  /// Get the first two columns from a number of records as an associative array where all the given conditions met.
o $DB->get_records_select_menu($table, $select, array $params=null, $sort='', $fields='*', $limitfrom=0, $limitnum=0)
  /// Get the first two columns from a number of records as an associative array which match a particular WHERE clause.
o $DB->get_records_sql_menu($sql, array $params=null, $limitfrom=0, $limitnum=0)
  /// Get the first two columns from a number of records as an associative array using a SQL statement.

  5. Seeing how many records match a given criterion

  o $DB->count_records($table, array $conditions=null)
  /// Count the records in a table where all the given conditions met.
o $DB->count_records_select($table, $select, array $params=null, $countitem="COUNT('x')")
  /// Count the records in a table which match a particular WHERE clause.
o $DB->count_records_sql($sql, array $params=null)
  /// Get the result of an SQL SELECT COUNT(...) query.


6. Seeing if one record exists

o $DB->record_exists($table, array $conditions=null)
  /// Test whether a record exists in a table where all the given conditions met.
o $DB->record_exists_select($table, $select, array $params=null)
  /// Test whether any records exists in a table which match a particular WHERE clause.
o $DB->record_exists_sql($sql, array $params=null)
  /// Test whether a SQL SELECT statement returns any records.

 7. Getting a particular field value from one record 

o $DB->get_field($table, $return, array $conditions, $strictness=IGNORE_MISSING)
  /// Get a single field value from a table record where all the given conditions met.
  /// @param int $strictness
  ///   IGNORE_MISSING means compatible mode, false returned if record not found, debug message if more found;
  ///   IGNORE_MULTIPLE means return first, ignore multiple records found(not recommended);
  ///   MUST_EXIST means throw exception if no record or multiple records found
o $DB->get_field_select($table, $return, $select, array $params=null, $strictness=IGNORE_MISSING)
  /// Get a single field value from a table record which match a particular WHERE clause.
o $DB->get_field_sql($sql, array $params=null, $strictness=IGNORE_MISSING)
  /// Get a single field value (first field) using a SQL statement.

 8. Getting a particular field value from various records 

 o $DB->get_fieldset_select($table, $return, $select, array $params=null)
  /// Selects records and return values of chosen field as an array which match a particular WHERE clause.
o $DB->get_fieldset_sql($sql, array $params=null)
  /// Selects records and return values (first field) as an array using a SQL statement.


9. Setting a particular field in the database

o $DB->set_field($table, $newfield, $newvalue, array $conditions=null)
  /// Set a single field in every table record where all the given conditions met.
o $DB->set_field_select($table, $newfield, $newvalue, $select, array $params=null)
  /// Set a single field in every table record which match a particular WHERE clause.


10. Deleting Records

o $DB->delete_records($table, array $conditions=null)
  /// Delete the records from a table where all the given conditions met.
o $DB->delete_records_select($table, $select, array $params=null)
  /// Delete one or more records from a table which match a particular WHERE clause.

 11. Inserting Records

 The method to insert records is called aptly enough, insert_record(). The method accepts 4 parameters, but the fourth, "bulk", in most implementations is unused.

 $DB->insert_record($table, $dataobject, $returnid=true, $bulk=false)
  /// Insert a record into a table and return the "id" field if required.

  Starting with Moodle 2.7, you can do bulk record inserts using the following method call:

  /**
* Insert multiple records into database as fast as possible.
*
* Order of inserts is maintained, but the operation is not atomic, use transactions if necessary.
*
* This method is intended for inserting of large number of small objects, do not use for huge objects with text or binary fields.
*
* @param string $table  The database table to be inserted into
* @param array|Traversable $dataobjects list of objects to be inserted, must be compatible with foreach
* @return void does not return new record ids
*/
  $DB->insert_records($table, $dataobjects)

12. Updating Records

o $DB->update_record($table, $dataobject, $bulk=false)
  /// Update a record in a table.
  ///
  /// $dataobject is an object containing needed data
  /// Relies on $dataobject having a variable "id" to
  /// specify the record to update
  ///
  /// @param string $table The database table to be checked against.
  /// @param object $dataobject An object with contents equal to fieldname=>fieldvalue.
  ///        Must have an entry for 'id' to map to the table specified.
  /// @param bool $bulk true means repeated updates expected
  /// @return bool true
  /// @throws dml_exception if an error occurs.

  If you need to perform a more complex update using arbitrary SQL, you can use the 'execute' method. Only use this when nothing more specific will work


  o $DB->execute($sql, array $parms=null)
  /// Executes a general sql query. Should be used only when no other method suitable.
  /// Do NOT use this to make changes in db structure, use database_manager methods instead!
  /// @param string $sql query
  /// @param array $params query parameters
  /// @return bool true
  /// @throws dml_exception A DML specific exception is thrown for any errors.


13. Using Recordsets

Where the number of records to be retrieved from DB is high, the get_records_xxx() functions above are far from optimal, because they load all the records in memory at the same time. Under those circumstances, it is highly recommended to use these get_recordset_xxx() functions instead, which use one nice mechanism to iterate over all the target records and save a lot of memory.

Only one thing is absolutely important: Don't forget to close the recordsets after using them! (This will free up a lot of resources in the RDBMS).

Here is the general way to iterate over records using the get_recordset_xxx() functions:

$rs = $DB->get_recordset(....) {
foreach ($rs as $record) {
    // Do whatever you want with this record
}
$rs->close(); // Don't forget to close the recordset!
And this is the list of available functions (100% paired with the get_records_xxx() above):

o $DB->get_recordset($table, array $conditions=null, $sort='', $fields='*', $limitfrom=0, $limitnum=0)
  /// Get a number of records as a moodle_recordset where all the given conditions met.
o $DB->get_recordset_select($table, $select, array $params=null, $sort='', $fields='*', $limitfrom=0, $limitnum=0)
  /// Get a number of records as a moodle_recordset which match a particular WHERE clause.
o $DB->get_recordset_sql($sql, array $params=null, $limitfrom=0, $limitnum=0);
  /// Get a number of records as a moodle_recordset using a SQL statement.

o $DB->get_recordset_list($table, $field='', $values='', $sort='', $fields='*', $limitfrom='', $limitnum='')
  /// Get a number of records as a moodle_recordset where one field matches one list of values.
Unlike get_record functions, you cannot use $rs == true or !empty($rs) to determine if any records were found. Recordsets implement the standard PHP Iterator interface (http://uk.php.net/manual/en/class.iterator.php)

So,

if ($rs->valid()) {
    // The recordset contains records.
}

14. Delegated transactions

Please note some databases do not support transactions (such as the MyISAM MySQL database engine), however all server administrators are strongly encouraged to migrate to databases that support transactions (such as the InnoDB MySQL database engine).
Previous versions supported only one level of transaction. Since Moodle 2.0, the DML layer emulates delegated transactions that allow nesting of transactions.
Transactions should not be used much in Moodle core; they are intended for various plugins such as web services, enrol and auth plugins.
Some subsystems (such as messaging) do not support transactions because is it is not possible to rollback in external systems.
A transaction is started by:

$transaction = $DB->start_delegated_transaction();
and finished by:

$transaction->allow_commit();
Usually a transaction is rolled back when an exception is thrown. $transaction->rollback($ex); must be used very carefully because it might break compatibility with databases that do not support transactions. Transactions cannot be used as part of expected code flow; they can be used only as an emergency protection of data consistency.

See more details in DB layer 2.0 delegated transactions or MDL-20625.

15. SQL compatibility functions

In order have real cross-db compatibility, there are some helper functions used to build SQL fragments based on the DB Moodle is running. Using them we'll avoid conditional queries here and there and have those "incompatibilities" fixed once and for ever.

o $DB->sql_bitand($int1, $int2)
  /// Returns the SQL text to be used in order to perform one bitwise AND
  /// operation between 2 integers.
o $DB->sql_bitnot($int1)
  /// Returns the SQL text to be used in order to perform one bitwise NOT
  /// operation with 1 integer.
o $DB->sql_bitor($int1, $int2)
  /// Returns the SQL text to be used in order to perform one bitwise OR
  /// operation between 2 integers.
o $DB->sql_bitxor($int1, $int2)
  /// Returns the SQL text to be used in order to perform one bitwise XOR
  /// operation between 2 integers.

o $DB->sql_null_from_clause()
  /// Returns the FROM clause required by some DBs in all SELECT statements.

o $DB->sql_ceil($fieldname)
  /// Returns the correct CEIL expression applied to fieldname.
o $DB->sql_like($fieldname, $param, $casesensitive = true, $accentsensitive = true, $notlike = false, $escapechar = ' \\ ')
  /// Returns the proper SQL to do LIKE. For example:
  $DB->get_records_sql('SELECT ...  WHERE '.$DB->sql_like('idnumber', ':idnum').' ... ', array( 'idnum' => 'foo'));
  /// Note: Use $DB->sql_like_escape(...) when its user input from a form.

o $DB->sql_length($fieldname)
  /// Returns the SQL text to be used to calculate the length in characters of one expression.
o $DB->sql_modulo($int1, $int2)
  /// Returns the SQL text to be used in order to calculate module - remainder after division
o $DB->sql_position($needle, $haystack)
  /// Returns the SQL for returning searching one string for the location of another.
  /// Note: If using placeholders BOTH in $needle and $haystack, they MUST be named placeholders.
o $DB->sql_substr($expr, $start, $length=false)
  /// Returns the proper substr() SQL text used to extract substrings from DB.
  /// Note: This fuction has changed in Moodle 2.0 and now at least 2 params are mandatory.
  /// Note: Now it returns the whole SQL text to be used instead of only the function name.

o $DB->sql_cast_char2int($fieldname, $text=false)
  /// Returns the SQL to be used in order to CAST one CHAR column to INTEGER.
o $DB->sql_cast_char2real($fieldname, $text=false)
  /// Returns the SQL to be used in order to CAST one CHAR column to REAL number.

o $DB->sql_compare_text($fieldname, $numchars=32)
  /// Returns the SQL text to be used to compare one TEXT (clob) column.
  /// with one VARCHAR column.
o $DB->sql_order_by_text($fieldname, $numchars=32)
  /// Returns the SQL text to be used to order by one TEXT (clob) column.

o $DB->sql_concat()
  /// Returns the proper SQL to do CONCAT between the elements passed.
o $DB->sql_concat_join($separator="' '", $elements=array())
  /// Returns the proper SQL to do CONCAT between the elements passed using one separator.
o $DB->sql_fullname($first='firstname', $last='lastname')
  /// Returns the proper SQL to concatenate $firstname and $lastname.

o $DB->sql_isempty($tablename, $fieldname, $nullablefield, $textfield)
  /// Returns the proper SQL to know if one field is empty.
o $DB->sql_isnotempty($tablename, $fieldname, $nullablefield, $textfield)
  /// Returns the proper SQL to know if one field is not empty.
o $DB->sql_empty()
  /// Returns the empty string char used by every supported DB.

o $DB->get_in_or_equal($items, $type=SQL_PARAMS_QM, $prefix='param', $equal=true, $onemptyitems=false)
  /// Constructs 'IN()' or '=' sql fragment

16. Debug fuctions

If you execute

$DB->set_debug(true)
then $DB will outout the SQL of every query executed, along with timing information. This can be useful when debugging your code. Obviously, all such calls should be removed before code is submitted for integration.

17. Special cases

get_course
From Moodle 2.5.1 onwards, you should use the get_course function instead of using get_record('course', ...) if you want to get a course record based on its ID, especially if there is a significant possibility that the course being retrieved is either the current course for the page, or the site course. Those two course records have probably already been loaded, and using this function will save a database query.

As another advantage, the code is shorter and easier to read.

Replace:

   $course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST);
With:

   $course = get_course($courseid);
get_courses
If you want to get all the current courses in your Moodle, use get_courses() without parameter:

   $courses = get_courses();



Official Docs:
1. https://docs.moodle.org/dev/Data_manipulation_API
2. https://docs.moodle.org/dev/SQL_coding_style
3. https://docs.moodle.org/dev/Core_APIs
4. https://docs.moodle.org/dev/DML_exceptions

No comments:

Post a Comment