const SLOW_WRITE_SEC = 0.500;
const SMALL_WRITE_ROWS = 100;
+ /** @var string Whether lock granularity is on the level of the entire database */
+ const ATTR_DB_LEVEL_LOCKING = 'db-level-locking';
+
/** @var string SQL query */
protected $lastQuery = '';
/** @var float|bool UNIX timestamp of last write query */
return $conn;
}
+ /**
+ * @param string $dbType A possible DB type (sqlite, mysql, postgres,...)
+ * @param string|null $driver Optional name of a specific DB client driver
+ * @return array Map of (Database::ATTRIBUTE_* constant => value) for all such constants
+ * @throws InvalidArgumentException
+ * @since 1.31
+ */
+ final public static function attributesFromType( $dbType, $driver = null ) {
+ static $defaults = [ self::ATTR_DB_LEVEL_LOCKING => false ];
+
+ $class = self::getClass( $dbType, $driver );
+
+ return call_user_func( [ $class, 'getAttributes' ] ) + $defaults;
+ }
+
/**
* @param string $dbType A possible DB type (sqlite, mysql, postgres,...)
* @param string|null $driver Optional name of a specific DB client driver
return $class;
}
+ /**
+ * @return array Map of (Database::ATTRIBUTE_* constant => value
+ * @since 1.31
+ */
+ protected static function getAttributes() {
+ return [];
+ }
+
/**
* Set the PSR-3 logger interface to use for query logging. (The logger
* interfaces for connection logging and error logging can be set with the
return '(' . $this->selectSQLText( $table, $fld, $conds, null, [], $join_conds ) . ')';
}
+ public function buildSubstring( $input, $startPosition, $length = null ) {
+ $this->assertBuildSubstringParams( $startPosition, $length );
+ $functionBody = "$input FROM $startPosition";
+ if ( $length !== null ) {
+ $functionBody .= " FOR $length";
+ }
+ return 'SUBSTRING(' . $functionBody . ')';
+ }
+
+ /**
+ * Check type and bounds for parameters to self::buildSubstring()
+ *
+ * All supported databases have substring functions that behave the same for
+ * positive $startPosition and non-negative $length, but behaviors differ when
+ * given 0 or negative $startPosition or negative $length. The simplest
+ * solution to that is to just forbid those values.
+ *
+ * @param int $startPosition
+ * @param int|null $length
+ * @since 1.31
+ */
+ protected function assertBuildSubstringParams( $startPosition, $length ) {
+ if ( !is_int( $startPosition ) || $startPosition <= 0 ) {
+ throw new InvalidArgumentException(
+ '$startPosition must be a positive integer'
+ );
+ }
+ if ( !( is_int( $length ) && $length >= 0 || $length === null ) ) {
+ throw new InvalidArgumentException(
+ '$length must be null or an integer greater than or equal to 0'
+ );
+ }
+ }
+
public function buildStringCast( $field ) {
return $field;
}
+ public function buildIntegerCast( $field ) {
+ return 'CAST( ' . $field . ' AS INTEGER )';
+ }
+
public function databasesAreIndependent() {
return false;
}
}
// We can't separate explicit JOIN clauses with ',', use ' ' for those
- $implicitJoins = !empty( $ret ) ? implode( ',', $ret ) : "";
- $explicitJoins = !empty( $retJOIN ) ? implode( ' ', $retJOIN ) : "";
+ $implicitJoins = $ret ? implode( ',', $ret ) : "";
+ $explicitJoins = $retJOIN ? implode( ' ', $retJOIN ) : "";
// Compile our final table clause
return implode( ' ', [ $implicitJoins, $explicitJoins ] );