Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like DatabasePostgres often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use DatabasePostgres, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 207 | class DatabasePostgres extends Database { |
||
| 208 | /** @var resource */ |
||
| 209 | protected $mLastResult = null; |
||
| 210 | |||
| 211 | /** @var int The number of rows affected as an integer */ |
||
| 212 | protected $mAffectedRows = null; |
||
| 213 | |||
| 214 | /** @var int */ |
||
| 215 | private $mInsertId = null; |
||
| 216 | |||
| 217 | /** @var float|string */ |
||
| 218 | private $numericVersion = null; |
||
| 219 | |||
| 220 | /** @var string Connect string to open a PostgreSQL connection */ |
||
| 221 | private $connectString; |
||
| 222 | |||
| 223 | /** @var string */ |
||
| 224 | private $mCoreSchema; |
||
| 225 | |||
| 226 | function getType() { |
||
| 229 | |||
| 230 | function cascadingDeletes() { |
||
| 233 | |||
| 234 | function cleanupTriggers() { |
||
| 237 | |||
| 238 | function strictIPs() { |
||
| 241 | |||
| 242 | function realTimestamps() { |
||
| 245 | |||
| 246 | function implicitGroupby() { |
||
| 249 | |||
| 250 | function implicitOrderby() { |
||
| 253 | |||
| 254 | function searchableIPs() { |
||
| 257 | |||
| 258 | function functionalIndexes() { |
||
| 261 | |||
| 262 | function hasConstraint( $name ) { |
||
| 271 | |||
| 272 | /** |
||
| 273 | * Usually aborts on failure |
||
| 274 | * @param string $server |
||
| 275 | * @param string $user |
||
| 276 | * @param string $password |
||
| 277 | * @param string $dbName |
||
| 278 | * @throws DBConnectionError|Exception |
||
| 279 | * @return DatabaseBase|null |
||
| 280 | */ |
||
| 281 | function open( $server, $user, $password, $dbName ) { |
||
| 361 | |||
| 362 | /** |
||
| 363 | * Postgres doesn't support selectDB in the same way MySQL does. So if the |
||
| 364 | * DB name doesn't match the open connection, open a new one |
||
| 365 | * @param string $db |
||
| 366 | * @return bool |
||
| 367 | */ |
||
| 368 | function selectDB( $db ) { |
||
| 375 | |||
| 376 | function makeConnectionString( $vars ) { |
||
| 384 | |||
| 385 | /** |
||
| 386 | * Closes a database connection, if it is open |
||
| 387 | * Returns success, true if already closed |
||
| 388 | * @return bool |
||
| 389 | */ |
||
| 390 | protected function closeConnection() { |
||
| 393 | |||
| 394 | public function doQuery( $sql ) { |
||
| 411 | |||
| 412 | protected function dumpError() { |
||
| 432 | |||
| 433 | function reportQueryError( $error, $errno, $sql, $fname, $tempIgnore = false ) { |
||
| 450 | |||
| 451 | function queryIgnore( $sql, $fname = __METHOD__ ) { |
||
| 454 | |||
| 455 | /** |
||
| 456 | * @param stdClass|ResultWrapper $res |
||
| 457 | * @throws DBUnexpectedError |
||
| 458 | */ |
||
| 459 | View Code Duplication | function freeResult( $res ) { |
|
| 470 | |||
| 471 | /** |
||
| 472 | * @param ResultWrapper|stdClass $res |
||
| 473 | * @return stdClass |
||
| 474 | * @throws DBUnexpectedError |
||
| 475 | */ |
||
| 476 | View Code Duplication | function fetchObject( $res ) { |
|
| 496 | |||
| 497 | View Code Duplication | function fetchRow( $res ) { |
|
| 513 | |||
| 514 | View Code Duplication | function numRows( $res ) { |
|
| 530 | |||
| 531 | function numFields( $res ) { |
||
| 538 | |||
| 539 | function fieldName( $res, $n ) { |
||
| 546 | |||
| 547 | /** |
||
| 548 | * Return the result of the last call to nextSequenceValue(); |
||
| 549 | * This must be called after nextSequenceValue(). |
||
| 550 | * |
||
| 551 | * @return int|null |
||
| 552 | */ |
||
| 553 | function insertId() { |
||
| 556 | |||
| 557 | /** |
||
| 558 | * @param mixed $res |
||
| 559 | * @param int $row |
||
| 560 | * @return bool |
||
| 561 | */ |
||
| 562 | function dataSeek( $res, $row ) { |
||
| 569 | |||
| 570 | function lastError() { |
||
| 581 | |||
| 582 | function lastErrno() { |
||
| 589 | |||
| 590 | function affectedRows() { |
||
| 601 | |||
| 602 | /** |
||
| 603 | * Estimate rows in dataset |
||
| 604 | * Returns estimated count, based on EXPLAIN output |
||
| 605 | * This is not necessarily an accurate estimate, so use sparingly |
||
| 606 | * Returns -1 if count cannot be found |
||
| 607 | * Takes same arguments as Database::select() |
||
| 608 | * |
||
| 609 | * @param string $table |
||
| 610 | * @param string $vars |
||
| 611 | * @param string $conds |
||
| 612 | * @param string $fname |
||
| 613 | * @param array $options |
||
| 614 | * @return int |
||
| 615 | */ |
||
| 616 | View Code Duplication | function estimateRowCount( $table, $vars = '*', $conds = '', |
|
| 632 | |||
| 633 | /** |
||
| 634 | * Returns information about an index |
||
| 635 | * If errors are explicitly ignored, returns NULL on failure |
||
| 636 | * |
||
| 637 | * @param string $table |
||
| 638 | * @param string $index |
||
| 639 | * @param string $fname |
||
| 640 | * @return bool|null |
||
| 641 | */ |
||
| 642 | function indexInfo( $table, $index, $fname = __METHOD__ ) { |
||
| 656 | |||
| 657 | /** |
||
| 658 | * Returns is of attributes used in index |
||
| 659 | * |
||
| 660 | * @since 1.19 |
||
| 661 | * @param string $index |
||
| 662 | * @param bool|string $schema |
||
| 663 | * @return array |
||
| 664 | */ |
||
| 665 | function indexAttributes( $index, $schema = false ) { |
||
| 721 | |||
| 722 | function indexUnique( $table, $index, $fname = __METHOD__ ) { |
||
| 734 | |||
| 735 | /** |
||
| 736 | * Change the FOR UPDATE option as necessary based on the join conditions. Then pass |
||
| 737 | * to the parent function to get the actual SQL text. |
||
| 738 | * |
||
| 739 | * In Postgres when using FOR UPDATE, only the main table and tables that are inner joined |
||
| 740 | * can be locked. That means tables in an outer join cannot be FOR UPDATE locked. Trying to do |
||
| 741 | * so causes a DB error. This wrapper checks which tables can be locked and adjusts it accordingly. |
||
| 742 | * |
||
| 743 | * MySQL uses "ORDER BY NULL" as an optimization hint, but that syntax is illegal in PostgreSQL. |
||
| 744 | * @see DatabaseBase::selectSQLText |
||
| 745 | */ |
||
| 746 | function selectSQLText( $table, $vars, $conds = '', $fname = __METHOD__, |
||
| 768 | |||
| 769 | /** |
||
| 770 | * INSERT wrapper, inserts an array into a table |
||
| 771 | * |
||
| 772 | * $args may be a single associative array, or an array of these with numeric keys, |
||
| 773 | * for multi-row insert (Postgres version 8.2 and above only). |
||
| 774 | * |
||
| 775 | * @param string $table Name of the table to insert to. |
||
| 776 | * @param array $args Items to insert into the table. |
||
| 777 | * @param string $fname Name of the function, for profiling |
||
| 778 | * @param array|string $options String or array. Valid options: IGNORE |
||
| 779 | * @return bool Success of insert operation. IGNORE always returns true. |
||
| 780 | */ |
||
| 781 | function insert( $table, $args, $fname = __METHOD__, $options = [] ) { |
||
| 888 | |||
| 889 | /** |
||
| 890 | * INSERT SELECT wrapper |
||
| 891 | * $varMap must be an associative array of the form [ 'dest1' => 'source1', ... ] |
||
| 892 | * Source items may be literals rather then field names, but strings should |
||
| 893 | * be quoted with Database::addQuotes() |
||
| 894 | * $conds may be "*" to copy the whole table |
||
| 895 | * srcTable may be an array of tables. |
||
| 896 | * @todo FIXME: Implement this a little better (seperate select/insert)? |
||
| 897 | * |
||
| 898 | * @param string $destTable |
||
| 899 | * @param array|string $srcTable |
||
| 900 | * @param array $varMap |
||
| 901 | * @param array $conds |
||
| 902 | * @param string $fname |
||
| 903 | * @param array $insertOptions |
||
| 904 | * @param array $selectOptions |
||
| 905 | * @return bool |
||
| 906 | */ |
||
| 907 | function nativeInsertSelect( $destTable, $srcTable, $varMap, $conds, $fname = __METHOD__, |
||
| 908 | $insertOptions = [], $selectOptions = [] ) { |
||
| 909 | $destTable = $this->tableName( $destTable ); |
||
| 910 | |||
| 911 | if ( !is_array( $insertOptions ) ) { |
||
| 912 | $insertOptions = [ $insertOptions ]; |
||
| 913 | } |
||
| 914 | |||
| 915 | /* |
||
| 916 | * If IGNORE is set, we use savepoints to emulate mysql's behavior |
||
| 917 | * Ignore LOW PRIORITY option, since it is MySQL-specific |
||
| 918 | */ |
||
| 919 | $savepoint = null; |
||
| 920 | View Code Duplication | if ( in_array( 'IGNORE', $insertOptions ) ) { |
|
| 921 | $savepoint = new SavepointPostgres( $this, 'mw' ); |
||
| 922 | $olde = error_reporting( 0 ); |
||
| 923 | $numrowsinserted = 0; |
||
| 924 | $savepoint->savepoint(); |
||
| 925 | } |
||
| 926 | |||
| 927 | if ( !is_array( $selectOptions ) ) { |
||
| 928 | $selectOptions = [ $selectOptions ]; |
||
| 929 | } |
||
| 930 | list( $startOpts, $useIndex, $tailOpts ) = $this->makeSelectOptions( $selectOptions ); |
||
| 931 | View Code Duplication | if ( is_array( $srcTable ) ) { |
|
| 932 | $srcTable = implode( ',', array_map( [ &$this, 'tableName' ], $srcTable ) ); |
||
| 933 | } else { |
||
| 934 | $srcTable = $this->tableName( $srcTable ); |
||
| 935 | } |
||
| 936 | |||
| 937 | $sql = "INSERT INTO $destTable (" . implode( ',', array_keys( $varMap ) ) . ')' . |
||
| 938 | " SELECT $startOpts " . implode( ',', $varMap ) . |
||
| 939 | " FROM $srcTable $useIndex"; |
||
| 940 | |||
| 941 | if ( $conds != '*' ) { |
||
| 942 | $sql .= ' WHERE ' . $this->makeList( $conds, LIST_AND ); |
||
| 943 | } |
||
| 944 | |||
| 945 | $sql .= " $tailOpts"; |
||
| 946 | |||
| 947 | $res = (bool)$this->query( $sql, $fname, $savepoint ); |
||
| 948 | if ( $savepoint ) { |
||
| 949 | $bar = pg_result_error( $this->mLastResult ); |
||
| 950 | if ( $bar != false ) { |
||
| 951 | $savepoint->rollback(); |
||
| 952 | } else { |
||
| 953 | $savepoint->release(); |
||
| 954 | $numrowsinserted++; |
||
| 955 | } |
||
| 956 | error_reporting( $olde ); |
||
| 957 | $savepoint->commit(); |
||
| 958 | |||
| 959 | // Set the affected row count for the whole operation |
||
| 960 | $this->mAffectedRows = $numrowsinserted; |
||
| 961 | |||
| 962 | // IGNORE always returns true |
||
| 963 | return true; |
||
| 964 | } |
||
| 965 | |||
| 966 | return $res; |
||
| 967 | } |
||
| 968 | |||
| 969 | View Code Duplication | function tableName( $name, $format = 'quoted' ) { |
|
| 980 | |||
| 981 | /* Don't cheat on installer */ |
||
| 982 | function realTableName( $name, $format = 'quoted' ) { |
||
| 985 | |||
| 986 | /** |
||
| 987 | * Return the next in a sequence, save the value for retrieval via insertId() |
||
| 988 | * |
||
| 989 | * @param string $seqName |
||
| 990 | * @return int|null |
||
| 991 | */ |
||
| 992 | function nextSequenceValue( $seqName ) { |
||
| 1000 | |||
| 1001 | /** |
||
| 1002 | * Return the current value of a sequence. Assumes it has been nextval'ed in this session. |
||
| 1003 | * |
||
| 1004 | * @param string $seqName |
||
| 1005 | * @return int |
||
| 1006 | */ |
||
| 1007 | function currentSequenceValue( $seqName ) { |
||
| 1015 | |||
| 1016 | # Returns the size of a text field, or -1 for "unlimited" |
||
| 1017 | function textFieldSize( $table, $field ) { |
||
| 1033 | |||
| 1034 | function limitResult( $sql, $limit, $offset = false ) { |
||
| 1037 | |||
| 1038 | function wasDeadlock() { |
||
| 1041 | |||
| 1042 | function duplicateTableStructure( $oldName, $newName, $temporary = false, $fname = __METHOD__ ) { |
||
| 1049 | |||
| 1050 | function listTables( $prefix = null, $fname = __METHOD__ ) { |
||
| 1065 | |||
| 1066 | function timestamp( $ts = 0 ) { |
||
| 1069 | |||
| 1070 | /** |
||
| 1071 | * Posted by cc[plus]php[at]c2se[dot]com on 25-Mar-2009 09:12 |
||
| 1072 | * to http://www.php.net/manual/en/ref.pgsql.php |
||
| 1073 | * |
||
| 1074 | * Parsing a postgres array can be a tricky problem, he's my |
||
| 1075 | * take on this, it handles multi-dimensional arrays plus |
||
| 1076 | * escaping using a nasty regexp to determine the limits of each |
||
| 1077 | * data-item. |
||
| 1078 | * |
||
| 1079 | * This should really be handled by PHP PostgreSQL module |
||
| 1080 | * |
||
| 1081 | * @since 1.19 |
||
| 1082 | * @param string $text Postgreql array returned in a text form like {a,b} |
||
| 1083 | * @param string $output |
||
| 1084 | * @param int $limit |
||
| 1085 | * @param int $offset |
||
| 1086 | * @return string |
||
| 1087 | */ |
||
| 1088 | function pg_array_parse( $text, &$output, $limit = false, $offset = 1 ) { |
||
| 1114 | |||
| 1115 | /** |
||
| 1116 | * Return aggregated value function call |
||
| 1117 | * @param array $valuedata |
||
| 1118 | * @param string $valuename |
||
| 1119 | * @return array |
||
| 1120 | */ |
||
| 1121 | public function aggregateValue( $valuedata, $valuename = 'value' ) { |
||
| 1124 | |||
| 1125 | /** |
||
| 1126 | * @return string Wikitext of a link to the server software's web site |
||
| 1127 | */ |
||
| 1128 | public function getSoftwareLink() { |
||
| 1131 | |||
| 1132 | /** |
||
| 1133 | * Return current schema (executes SELECT current_schema()) |
||
| 1134 | * Needs transaction |
||
| 1135 | * |
||
| 1136 | * @since 1.19 |
||
| 1137 | * @return string Default schema for the current session |
||
| 1138 | */ |
||
| 1139 | function getCurrentSchema() { |
||
| 1145 | |||
| 1146 | /** |
||
| 1147 | * Return list of schemas which are accessible without schema name |
||
| 1148 | * This is list does not contain magic keywords like "$user" |
||
| 1149 | * Needs transaction |
||
| 1150 | * |
||
| 1151 | * @see getSearchPath() |
||
| 1152 | * @see setSearchPath() |
||
| 1153 | * @since 1.19 |
||
| 1154 | * @return array List of actual schemas for the current sesson |
||
| 1155 | */ |
||
| 1156 | function getSchemas() { |
||
| 1165 | |||
| 1166 | /** |
||
| 1167 | * Return search patch for schemas |
||
| 1168 | * This is different from getSchemas() since it contain magic keywords |
||
| 1169 | * (like "$user"). |
||
| 1170 | * Needs transaction |
||
| 1171 | * |
||
| 1172 | * @since 1.19 |
||
| 1173 | * @return array How to search for table names schemas for the current user |
||
| 1174 | */ |
||
| 1175 | function getSearchPath() { |
||
| 1183 | |||
| 1184 | /** |
||
| 1185 | * Update search_path, values should already be sanitized |
||
| 1186 | * Values may contain magic keywords like "$user" |
||
| 1187 | * @since 1.19 |
||
| 1188 | * |
||
| 1189 | * @param array $search_path List of schemas to be searched by default |
||
| 1190 | */ |
||
| 1191 | function setSearchPath( $search_path ) { |
||
| 1194 | |||
| 1195 | /** |
||
| 1196 | * Determine default schema for MediaWiki core |
||
| 1197 | * Adjust this session schema search path if desired schema exists |
||
| 1198 | * and is not alread there. |
||
| 1199 | * |
||
| 1200 | * We need to have name of the core schema stored to be able |
||
| 1201 | * to query database metadata. |
||
| 1202 | * |
||
| 1203 | * This will be also called by the installer after the schema is created |
||
| 1204 | * |
||
| 1205 | * @since 1.19 |
||
| 1206 | * |
||
| 1207 | * @param string $desiredSchema |
||
| 1208 | */ |
||
| 1209 | function determineCoreSchema( $desiredSchema ) { |
||
| 1236 | |||
| 1237 | /** |
||
| 1238 | * Return schema name fore core MediaWiki tables |
||
| 1239 | * |
||
| 1240 | * @since 1.19 |
||
| 1241 | * @return string Core schema name |
||
| 1242 | */ |
||
| 1243 | function getCoreSchema() { |
||
| 1246 | |||
| 1247 | /** |
||
| 1248 | * @return string Version information from the database |
||
| 1249 | */ |
||
| 1250 | function getServerVersion() { |
||
| 1267 | |||
| 1268 | /** |
||
| 1269 | * Query whether a given relation exists (in the given schema, or the |
||
| 1270 | * default mw one if not given) |
||
| 1271 | * @param string $table |
||
| 1272 | * @param array|string $types |
||
| 1273 | * @param bool|string $schema |
||
| 1274 | * @return bool |
||
| 1275 | */ |
||
| 1276 | function relationExists( $table, $types, $schema = false ) { |
||
| 1294 | |||
| 1295 | /** |
||
| 1296 | * For backward compatibility, this function checks both tables and |
||
| 1297 | * views. |
||
| 1298 | * @param string $table |
||
| 1299 | * @param string $fname |
||
| 1300 | * @param bool|string $schema |
||
| 1301 | * @return bool |
||
| 1302 | */ |
||
| 1303 | function tableExists( $table, $fname = __METHOD__, $schema = false ) { |
||
| 1306 | |||
| 1307 | function sequenceExists( $sequence, $schema = false ) { |
||
| 1310 | |||
| 1311 | View Code Duplication | function triggerExists( $table, $trigger ) { |
|
| 1333 | |||
| 1334 | function ruleExists( $table, $rule ) { |
||
| 1345 | |||
| 1346 | View Code Duplication | function constraintExists( $table, $constraint ) { |
|
| 1361 | |||
| 1362 | /** |
||
| 1363 | * Query whether a given schema exists. Returns true if it does, false if it doesn't. |
||
| 1364 | * @param string $schema |
||
| 1365 | * @return bool |
||
| 1366 | */ |
||
| 1367 | function schemaExists( $schema ) { |
||
| 1373 | |||
| 1374 | /** |
||
| 1375 | * Returns true if a given role (i.e. user) exists, false otherwise. |
||
| 1376 | * @param string $roleName |
||
| 1377 | * @return bool |
||
| 1378 | */ |
||
| 1379 | function roleExists( $roleName ) { |
||
| 1385 | |||
| 1386 | /** |
||
| 1387 | * @var string $table |
||
| 1388 | * @var string $field |
||
| 1389 | * @return PostgresField|null |
||
| 1390 | */ |
||
| 1391 | function fieldInfo( $table, $field ) { |
||
| 1394 | |||
| 1395 | /** |
||
| 1396 | * pg_field_type() wrapper |
||
| 1397 | * @param ResultWrapper|resource $res ResultWrapper or PostgreSQL query result resource |
||
| 1398 | * @param int $index Field number, starting from 0 |
||
| 1399 | * @return string |
||
| 1400 | */ |
||
| 1401 | function fieldType( $res, $index ) { |
||
| 1408 | |||
| 1409 | /** |
||
| 1410 | * @param string $b |
||
| 1411 | * @return Blob |
||
| 1412 | */ |
||
| 1413 | function encodeBlob( $b ) { |
||
| 1416 | |||
| 1417 | function decodeBlob( $b ) { |
||
| 1426 | |||
| 1427 | function strencode( $s ) { |
||
| 1432 | |||
| 1433 | /** |
||
| 1434 | * @param null|bool|Blob $s |
||
| 1435 | * @return int|string |
||
| 1436 | */ |
||
| 1437 | function addQuotes( $s ) { |
||
| 1453 | |||
| 1454 | /** |
||
| 1455 | * Postgres specific version of replaceVars. |
||
| 1456 | * Calls the parent version in Database.php |
||
| 1457 | * |
||
| 1458 | * @param string $ins SQL string, read from a stream (usually tables.sql) |
||
| 1459 | * @return string SQL string |
||
| 1460 | */ |
||
| 1461 | protected function replaceVars( $ins ) { |
||
| 1475 | |||
| 1476 | /** |
||
| 1477 | * Various select options |
||
| 1478 | * |
||
| 1479 | * @param array $options An associative array of options to be turned into |
||
| 1480 | * an SQL query, valid keys are listed in the function. |
||
| 1481 | * @return array |
||
| 1482 | */ |
||
| 1483 | function makeSelectOptions( $options ) { |
||
| 1517 | |||
| 1518 | function getDBname() { |
||
| 1521 | |||
| 1522 | function getServer() { |
||
| 1525 | |||
| 1526 | function buildConcat( $stringList ) { |
||
| 1529 | |||
| 1530 | View Code Duplication | public function buildGroupConcatField( |
|
| 1537 | |||
| 1538 | /** |
||
| 1539 | * @param string $field Field or column to cast |
||
| 1540 | * @return string |
||
| 1541 | * @since 1.28 |
||
| 1542 | */ |
||
| 1543 | public function buildStringCast( $field ) { |
||
| 1546 | |||
| 1547 | public function getSearchEngine() { |
||
| 1550 | |||
| 1551 | public function streamStatementEnd( &$sql, &$newLine ) { |
||
| 1563 | |||
| 1564 | /** |
||
| 1565 | * Check to see if a named lock is available. This is non-blocking. |
||
| 1566 | * See http://www.postgresql.org/docs/8.2/static/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS |
||
| 1567 | * |
||
| 1568 | * @param string $lockName Name of lock to poll |
||
| 1569 | * @param string $method Name of method calling us |
||
| 1570 | * @return bool |
||
| 1571 | * @since 1.20 |
||
| 1572 | */ |
||
| 1573 | View Code Duplication | public function lockIsFree( $lockName, $method ) { |
|
| 1581 | |||
| 1582 | /** |
||
| 1583 | * See http://www.postgresql.org/docs/8.2/static/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS |
||
| 1584 | * @param string $lockName |
||
| 1585 | * @param string $method |
||
| 1586 | * @param int $timeout |
||
| 1587 | * @return bool |
||
| 1588 | */ |
||
| 1589 | public function lock( $lockName, $method, $timeout = 5 ) { |
||
| 1607 | |||
| 1608 | /** |
||
| 1609 | * See http://www.postgresql.org/docs/8.2/static/functions-admin.html#FUNCTIONS-ADVISORY-LOCKSFROM |
||
| 1610 | * PG DOCS: http://www.postgresql.org/docs/8.2/static/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS |
||
| 1611 | * @param string $lockName |
||
| 1612 | * @param string $method |
||
| 1613 | * @return bool |
||
| 1614 | */ |
||
| 1615 | View Code Duplication | public function unlock( $lockName, $method ) { |
|
| 1629 | |||
| 1630 | /** |
||
| 1631 | * @param string $lockName |
||
| 1632 | * @return string Integer |
||
| 1633 | */ |
||
| 1634 | private function bigintFromLockName( $lockName ) { |
||
| 1637 | } // end DatabasePostgres class |
||
| 1638 | |||
| 1641 |
Only declaring a single property per statement allows you to later on add doc comments more easily.
It is also recommended by PSR2, so it is a common style that many people expect.