[WIP] Upsert support prototype. #163

Closed
wants to merge 6 commits into from

6 participants

@kimhemsoe
Doctrine member

No description provided.

@beberlei
Doctrine member

You committed a .DS_STORE file, please remove it.

@beberlei beberlei commented on an outdated diff Jun 29, 2012
lib/Doctrine/DBAL/Connection.php
+ * @param array $data An associative array containing column-value pairs.
+ * @param array $identifier
+ * @param array $types
+ * @return intt
+ */
+ public function upsert($tableName, array $data, array $identifier, array $types = array())
+ {
+ $this->connect();
+
+ if ($this->_platform->supportsNativeUpsert()) {
+ list ($sql, $params, $types) = $this->_platform->getUpsertSql($tableName, $data, $identifier, $types);
+ return $this->executeUpdate($sql, $params, $types);
+ } else {
+ $sql = 'SELECT COUNT(*) FROM ' . $tableName
+ . ' WHERE ' . implode(' = ? AND ', array_keys($identifier))
+ . ' = ?';
@beberlei
Doctrine member

Should be with locking, since otherwise the row could be deleted in that timeframe.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@kimhemsoe kimhemsoe [UPSERT] Removed a sneaky .DS_Store file.
[UPSERT] Added locking when not using native upsert support.
a2f602d
@travisbot

This pull request fails (merged 3322794 into 4eaa44c).

@travisbot

This pull request fails (merged a2f602d into 4eaa44c).

@travisbot

This pull request fails (merged 024410a into 4eaa44c).

@travisbot

This pull request passes (merged 03840fc into 4eaa44c).

@stof stof commented on an outdated diff Jul 2, 2012
lib/Doctrine/DBAL/Connection.php
@@ -540,6 +540,39 @@ public function insert($tableName, array $data, array $types = array())
}
/**
+ *
+ * @param string $tableName The name of the table to insert data into.
+ * @param array $data An associative array containing column-value pairs.
+ * @param array $identifier
+ * @param array $types
+ * @return int
+ */
+ public function upsert($tableName, array $data, array $identifier, array $types = array())
+ {
+ $this->connect();
+
+ if ($this->_platform->supportsNativeUpsert()) {
+ list ($sql, $params, $types) = $this->_platform->getUpsertSql($tableName, $data, $identifier, $types);
+ return $this->executeUpdate($sql, $params, $types);
+ } else {
@stof
Doctrine member
stof added a note Jul 2, 2012

no need to use else here as the if returns.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@stof stof commented on an outdated diff Jul 2, 2012
lib/Doctrine/DBAL/Connection.php
+ if ($this->_platform->supportsNativeUpsert()) {
+ list ($sql, $params, $types) = $this->_platform->getUpsertSql($tableName, $data, $identifier, $types);
+ return $this->executeUpdate($sql, $params, $types);
+ } else {
+ $sql = 'SELECT ' . implode(', ', array_keys($identifier)) . ' FROM ' . $tableName
+ . ' WHERE ' . implode(' = ? AND ', array_keys($identifier))
+ . ' = ?'
+ . ' ' . $this->_platform->getWriteLockSQL();
+
+ $stmt = $this->executeQuery($sql, array_values($identifier));
+ $haveRows = (bool)$stmt->fetch(PDO::FETCH_NUM);
+ $stmt->closeCursor();
+
+ if ($haveRows) {
+ return $this->update($tableName, $data, $identifier, $types);
+ } else {
@stof
Doctrine member
stof added a note Jul 2, 2012

same here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@beberlei beberlei commented on the diff Jul 5, 2012
lib/Doctrine/DBAL/Platforms/AbstractPlatform.php
@@ -2703,6 +2713,19 @@ public function rollbackSavePoint($savepoint)
}
/**
+ * @param type $tableName
+ * @param array $data
+ * @param array $identifier
+ * @param array $types
+ * @throws Doctrine\DBAL\DBALException
+ * @return array
+ */
+ public function getUpsertSql($tableName, array $data, array $identifier, array $types)
@beberlei
Doctrine member
beberlei added a note Jul 5, 2012

Why $types?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@kimhemsoe
Doctrine member

well.. it is a update or insert. was thinking i could follow the same rule as with update().

it is broken atm tho.

@stof
Doctrine member

btw, it seems a bit weird to add a way to support native upsert, but without supporting it in any platform.

@kimhemsoe
Doctrine member

I will add atleast mysql support before its getting merged.

@staabm

In mysql you could use REPLACE INTO instead, so only one statement will be required..

@beberlei
Doctrine member

-1 on REPLACE INTO, ON DUPLICATE KEY is much better.

@staabm

Is there any difference between a REPLACE INTO and INSERT ... ON DUPLICATE KEY..?

@kimhemsoe
Doctrine member

REPLACE into have some nasty side effects, cant find a good text about it right now. Another problem with replace is that it have no "where clause" ON DUPLICATE KEY is the same, but a little different as i use unique constraints for it.

It wont be possible to make upsert() to behave 100% the same on all platforms.

@beberlei
Doctrine member

if you have auto_increment on another oclumn than primary key, then REPLACE INTO will increment it.

Edit: In MySQL its literally implemented as DELETE, then INSERT INTO. Wheras ON DUPLICATE is an UPDATE.

@kimhemsoe
Doctrine member

Think we have the same problem with sqlite and replace there. Dont think we get any native support there anytime soon.

sqlserver and OCI8 have merge support and im hoping someone will do those.

postgre dont have anything easy accessible , but can be done on never versions with some magic or.. something.

Ive been thinking we may need a swith to turn off native support.

@staabm

@kimhemsoe @beberlei thanks for the explanation.

@kimhemsoe
Doctrine member

@mvrhov Thanks i will give a read, but..yeah it is giving me the shivers. It may end up with one big warning clause in the documentation :-P

kimhemsoe added some commits Sep 22, 2012
@kimhemsoe kimhemsoe tmp a5581ae
@kimhemsoe kimhemsoe Merge branch 'master' into upsert
Conflicts:
	lib/Doctrine/DBAL/Connection.php
4c261ef
@beberlei
Doctrine member

Closing for now, @deeky666 will work on a new solution in the future.

@beberlei beberlei closed this Dec 20, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment