Skip to content
Draft
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions misc/db-updates/2023-07-17/classic_data_objects.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
alter table itemCreators drop constraint itemCreators_ibfk_2;
DROP table creators;

DROP trigger if exists fki_itemCreators_libraryID;
DROP trigger if exists fku_itemCreators_libraryID;

CREATE TABLE `creators` (
`creatorID` bigint unsigned NOT NULL AUTO_INCREMENT,
`firstName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`lastName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`fieldMode` tinyint(1) unsigned DEFAULT NULL,
PRIMARY KEY (`creatorID`),
KEY `name` (`lastName`(7),`firstName`(6))
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will need to be a PHP script like the others that does a proper migration of existing data. It should set the shard to down, wait 20 seconds, do the migration, and bring the shard up.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. I only kept it as .sql until now for convenience.
I'll have it wrapped into the same algorithm as this update, except with state=down.

1 change: 1 addition & 0 deletions misc/master.sql
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ CREATE TABLE `libraries` (
`lastUpdated` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`version` int(10) unsigned NOT NULL DEFAULT '0',
`shardID` smallint(5) unsigned NOT NULL,
`hasData` TINYINT( 1 ) NOT NULL DEFAULT '0',

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to add this, but it shouldn't be in this PR.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can I push just this one line to master?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure.

PRIMARY KEY (`libraryID`),
KEY `shardID` (`shardID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Expand Down
2 changes: 1 addition & 1 deletion misc/shard.sql

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need all the schema changes here

Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ CREATE TABLE `syncDeleteLogIDs` (

CREATE TABLE `syncDeleteLogKeys` (
`libraryID` int(10) unsigned NOT NULL,
`objectType` enum('collection','creator','item','relation','search','setting','tag','tagName') NOT NULL,
`objectType` enum('collection','item','relation','search','setting','tag','tagName') NOT NULL,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tag should be removed

`key` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`version` int(10) unsigned NOT NULL DEFAULT '1',
Expand Down
159 changes: 18 additions & 141 deletions model/Creator.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,40 +27,30 @@
class Zotero_Creator {
private $id;
private $libraryID;
private $key;
private $firstName = '';
private $lastName = '';
private $shortName = '';
private $fieldMode = 0;
private $birthYear;
private $dateAdded;
private $dateModified;

private $loaded = false;
private $creatorTypeID;
private $changed = array();

public function __construct() {
$numArgs = func_num_args();
if ($numArgs) {
throw new Exception("Constructor doesn't take any parameters");
}

$this->init();
}



private function init() {
$this->loaded = false;

public function __construct($id, $libraryID, $firstName, $lastName, $fieldMode, $creatorTypeID = null) {
$this->id = $id;
$this->libraryID = $libraryID;
$this->firstName = $firstName;
$this->lastName = $lastName;
$this->fieldMode = $fieldMode;
$this->creatorTypeID = $creatorTypeID;
$this->changed = array();
$props = array(
'libraryID',
'firstName',
'lastName',
'shortName',
'fieldMode',
'birthYear',
'dateAdded',
'dateModified'
'creatorTypeID'
);
foreach ($props as $prop) {
$this->changed[$prop] = false;
Expand All @@ -69,10 +59,7 @@ private function init() {


public function __get($field) {
if (($this->id || $this->key) && !$this->loaded) {
$this->load(true);
}


if (!property_exists('Zotero_Creator', $field)) {
throw new Exception("Zotero_Creator property '$field' doesn't exist");
}
Expand All @@ -85,10 +72,6 @@ public function __set($field, $value) {
switch ($field) {
case 'id':
case 'libraryID':
case 'key':
if ($this->loaded) {
throw new Exception("Cannot set $field after creator is already loaded");
}
$this->checkValue($field, $value);
$this->$field = $value;
return;
Expand All @@ -99,15 +82,6 @@ public function __set($field, $value) {
break;
}

if ($this->id || $this->key) {
if (!$this->loaded) {
$this->load(true);
}
}
else {
$this->loaded = true;
}

$this->checkValue($field, $value);

if ($this->$field !== $value) {
Expand All @@ -117,20 +91,6 @@ public function __set($field, $value) {
}


/**
* Check if creator exists in the database
*
* @return bool TRUE if the item exists, FALSE if not
*/
public function exists() {
if (!$this->id) {
trigger_error('$this->id not set');
}

$sql = "SELECT COUNT(*) FROM creators WHERE creatorID=?";
return !!Zotero_DB::valueQuery($sql, $this->id, Zotero_Shards::getByLibraryID($this->libraryID));
}


public function hasChanged() {
return in_array(true, array_values($this->changed));
Expand All @@ -153,7 +113,7 @@ public function save($userID=false) {
throw new Exception('First name must be empty in single-field mode');
}

if (!$this->hasChanged()) {
if (!$this->hasChanged() && isset($this->id)) {
Z_Core::debug("Creator $this->id has not changed");
return false;
}
Expand All @@ -166,24 +126,13 @@ public function save($userID=false) {

Z_Core::debug("Saving creator $this->id");

$key = $this->key ? $this->key : Zotero_ID::getKey();

$timestamp = Zotero_DB::getTransactionTimestamp();

$dateAdded = $this->dateAdded ? $this->dateAdded : $timestamp;
$dateModified = !empty($this->changed['dateModified']) ? $this->dateModified : $timestamp;

$fields = "firstName=?, lastName=?, fieldMode=?,
libraryID=?, `key`=?, dateAdded=?, dateModified=?, serverDateModified=?";
$fields = "firstName=?, lastName=?, fieldMode=?";
$params = array(
$this->firstName,
$this->lastName,
$this->fieldMode,
$this->libraryID,
$key,
$dateAdded,
$dateModified,
$timestamp
$this->fieldMode
);
$shardID = Zotero_Shards::getByLibraryID($this->libraryID);

Expand All @@ -193,9 +142,6 @@ public function save($userID=false) {
$stmt = Zotero_DB::getStatement($sql, true, $shardID);
Zotero_DB::queryFromStatement($stmt, array_merge(array($creatorID), $params));

// Remove from delete log if it's there
$sql = "DELETE FROM syncDeleteLogKeys WHERE libraryID=? AND objectType='creator' AND `key`=?";
Zotero_DB::query($sql, array($this->libraryID, $key), $shardID);
}
else {
$sql = "UPDATE creators SET $fields WHERE creatorID=?";
Expand Down Expand Up @@ -234,18 +180,6 @@ public function save($userID=false) {

Zotero_DB::commit();

Zotero_Creators::cachePrimaryData(
array(
'id' => $creatorID,
'libraryID' => $this->libraryID,
'key' => $key,
'dateAdded' => $dateAdded,
'dateModified' => $dateModified,
'firstName' => $this->firstName,
'lastName' => $this->lastName,
'fieldMode' => $this->fieldMode
)
);
}
catch (Exception $e) {
Zotero_DB::rollback();
Expand All @@ -256,19 +190,13 @@ public function save($userID=false) {
if (!$this->id) {
$this->id = $creatorID;
}
if (!$this->key) {
$this->key = $key;
}

$this->init();


if ($isNew) {
Zotero_Creators::cache($this);
}

// TODO: invalidate memcache?

return $this->id;
}


Expand All @@ -294,53 +222,14 @@ public function getLinkedItems() {
}


public function equals($creator) {
if (!$this->loaded) {
$this->load();
}

public function equals($creator) {
return
($creator->firstName === $this->firstName) &&
($creator->lastName === $this->lastName) &&
($creator->fieldMode == $this->fieldMode);
}


private function load() {
if (!$this->libraryID) {
throw new Exception("Library ID not set");
}

if (!$this->id && !$this->key) {
throw new Exception("ID or key not set");
}

if ($this->id) {
//Z_Core::debug("Loading data for creator $this->libraryID/$this->id");
$row = Zotero_Creators::getPrimaryDataByID($this->libraryID, $this->id);
}
else {
//Z_Core::debug("Loading data for creator $this->libraryID/$this->key");
$row = Zotero_Creators::getPrimaryDataByKey($this->libraryID, $this->key);
}

$this->loaded = true;
$this->changed = array();

if (!$row) {
return;
}

if ($row['libraryID'] != $this->libraryID) {
throw new Exception("libraryID {$row['libraryID']} != $this->libraryID");
}

foreach ($row as $key=>$val) {
$this->$key = $val;
}
}


private function checkValue($field, $value) {
if (!property_exists($this, $field)) {
throw new Exception("Invalid property '$field'");
Expand All @@ -350,6 +239,7 @@ private function checkValue($field, $value) {
switch ($field) {
case 'id':
case 'libraryID':
case 'creatorTypeID':
if (!Zotero_Utilities::isPosInt($value)) {
$this->invalidValueError($field, $value);
}
Expand All @@ -360,19 +250,6 @@ private function checkValue($field, $value) {
$this->invalidValueError($field, $value);
}
break;

case 'key':
if (!preg_match('/^[23456789ABCDEFGHIJKMNPQRSTUVWXTZ]{8}$/', $value)) {
$this->invalidValueError($field, $value);
}
break;

case 'dateAdded':
case 'dateModified':
if ($value !== '' && !preg_match("/^[0-9]{4}\-[0-9]{2}\-[0-9]{2} ([0-1][0-9]|[2][0-3]):([0-5][0-9]):([0-5][0-9])$/", $value)) {
$this->invalidValueError($field, $value);
}
break;
}
}

Expand Down
Loading