<?php
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Database\Database;
use Drupal\Core\Utility\SchemaCache;
const SCHEMA_UNINSTALLED = -1;
const SCHEMA_INSTALLED = 0;
function drupal_get_schema($table = NULL, $rebuild = FALSE) {
static $schema;
if ($rebuild || !isset($table)) {
$schema = drupal_get_complete_schema($rebuild);
}
elseif (!isset($schema)) {
$schema = new SchemaCache();
}
if (!isset($table)) {
return $schema;
}
if (isset($schema[$table])) {
return $schema[$table];
}
else {
return FALSE;
}
}
function drupal_get_complete_schema($rebuild = FALSE) {
static $schema;
if (!isset($schema) || $rebuild) {
if (!$rebuild && ($cached = cache()
->get('schema'))) {
$schema = $cached->data;
}
else {
$schema = array();
if (function_exists('module_load_all_includes')) {
system_list_reset();
module_load_all_includes('install');
}
require_once DRUPAL_ROOT . '/core/includes/common.inc';
foreach (module_implements('schema') as $module) {
$current = (array) module_invoke($module, 'schema');
_drupal_schema_initialize($current, $module);
$schema = array_merge($schema, $current);
}
drupal_alter('schema', $schema);
if ($rebuild) {
cache()
->deleteTags(array(
'schema' => TRUE,
));
}
if (!empty($schema) && drupal_get_bootstrap_phase() == DRUPAL_BOOTSTRAP_FULL) {
cache()
->set('schema', $schema, CacheBackendInterface::CACHE_PERMANENT, array(
'schema' => TRUE,
));
}
}
}
return $schema;
}
function drupal_get_schema_versions($module) {
$updates =& drupal_static(__FUNCTION__, NULL);
if (!isset($updates[$module])) {
$updates = array();
foreach (module_list() as $loaded_module) {
$updates[$loaded_module] = array();
}
$regexp = '/^(?P<module>.+)_update_(?P<version>\\d+)$/';
$functions = get_defined_functions();
foreach (preg_grep('/_\\d+$/', $functions['user']) as $function) {
if (preg_match($regexp, $function, $matches)) {
$updates[$matches['module']][] = $matches['version'];
}
}
foreach ($updates as &$module_updates) {
sort($module_updates, SORT_NUMERIC);
}
}
return empty($updates[$module]) ? FALSE : $updates[$module];
}
function drupal_get_installed_schema_version($module, $reset = FALSE, $array = FALSE) {
static $versions = array();
if ($reset) {
$versions = array();
}
if (!$versions) {
if (!($versions = drupal_container()
->get('keyvalue')
->get('system.schema')
->getAll())) {
$versions = array();
}
}
if ($array) {
return $versions;
}
else {
return isset($versions[$module]) ? $versions[$module] : SCHEMA_UNINSTALLED;
}
}
function drupal_set_installed_schema_version($module, $version) {
drupal_container()
->get('keyvalue')
->get('system.schema')
->set($module, $version);
drupal_get_installed_schema_version(NULL, TRUE);
}
function drupal_install_schema($module) {
$schema = drupal_get_schema_unprocessed($module);
_drupal_schema_initialize($schema, $module, FALSE);
foreach ($schema as $name => $table) {
db_create_table($name, $table);
}
}
function drupal_uninstall_schema($module) {
$schema = drupal_get_schema_unprocessed($module);
_drupal_schema_initialize($schema, $module, FALSE);
foreach ($schema as $table) {
if (db_table_exists($table['name'])) {
db_drop_table($table['name']);
}
}
}
function drupal_get_schema_unprocessed($module, $table = NULL) {
module_load_install($module);
$schema = module_invoke($module, 'schema');
if (isset($table)) {
if (isset($schema[$table])) {
return $schema[$table];
}
return array();
}
elseif (!empty($schema)) {
return $schema;
}
return array();
}
function _drupal_schema_initialize(&$schema, $module, $remove_descriptions = TRUE) {
foreach ($schema as $name => &$table) {
if (empty($table['module'])) {
$table['module'] = $module;
}
if (!isset($table['name'])) {
$table['name'] = $name;
}
if ($remove_descriptions) {
unset($table['description']);
foreach ($table['fields'] as &$field) {
unset($field['description']);
}
}
}
}
function drupal_schema_fields_sql($table, $prefix = NULL) {
$schema = drupal_get_schema($table);
$fields = array_keys($schema['fields']);
if ($prefix) {
$columns = array();
foreach ($fields as $field) {
$columns[] = "{$prefix}.{$field}";
}
return $columns;
}
else {
return $fields;
}
}
function drupal_write_record($table, &$record, $primary_keys = array()) {
if (is_string($primary_keys)) {
$primary_keys = array(
$primary_keys,
);
}
$schema = drupal_get_schema($table);
if (empty($schema)) {
return FALSE;
}
$object = (object) $record;
$fields = array();
$default_fields = array();
foreach ($schema['fields'] as $field => $info) {
if ($info['type'] == 'serial') {
if (!empty($primary_keys)) {
continue;
}
$serial = $field;
}
if (in_array($field, $primary_keys)) {
continue;
}
if (!property_exists($object, $field)) {
$default_fields[] = $field;
continue;
}
if ($info['type'] == 'serial' && !isset($object->{$field})) {
$default_fields[] = $field;
continue;
}
if (empty($info['serialize'])) {
$fields[$field] = $object->{$field};
}
else {
$fields[$field] = serialize($object->{$field});
}
if (isset($object->{$field}) || !empty($info['not null'])) {
if ($info['type'] == 'int' || $info['type'] == 'serial') {
$fields[$field] = (int) $fields[$field];
}
elseif ($info['type'] == 'float') {
$fields[$field] = (double) $fields[$field];
}
else {
$fields[$field] = (string) $fields[$field];
}
}
}
if (empty($primary_keys)) {
$options = array(
'return' => Database::RETURN_INSERT_ID,
);
if (isset($serial) && isset($fields[$serial])) {
if ($fields[$serial]) {
$options['return'] = Database::RETURN_AFFECTED;
}
else {
unset($fields[$serial]);
}
}
$query = db_insert($table, $options)
->fields($fields)
->useDefaults($default_fields);
$return = SAVED_NEW;
}
else {
$query = db_update($table)
->fields($fields);
foreach ($primary_keys as $key) {
$query
->condition($key, $object->{$key});
}
$return = SAVED_UPDATED;
}
if ($query_return = $query
->execute()) {
if (isset($serial)) {
if (isset($options) && $options['return'] != Database::RETURN_INSERT_ID) {
$object->{$serial} = $fields[$serial];
}
else {
$object->{$serial} = $query_return;
}
}
}
elseif ($query_return === FALSE && count($primary_keys) == 1) {
$return = FALSE;
}
if (empty($primary_keys)) {
foreach ($schema['fields'] as $field => $info) {
if (isset($info['default']) && !property_exists($object, $field)) {
$object->{$field} = $info['default'];
}
}
}
if (is_array($record)) {
$record = (array) $object;
}
return $return;
}