Do you use replace within the datawriter or in model?

I put my replace function

  • in datawriter

    Votes: 3 60.0%
  • in model

    Votes: 2 40.0%

  • Total voters
    5

Marcus

Well-known member
There is no replace - mysql - function in ZEND. Do you do your "replace" stuff in the datawriter (checking for an existing id and updating it if it exists, otherwise create a new entry)? Or do you just use "REPLACE ..." in your model (I do that)? However I would love to hear benefits of using replace in the datawriter, although it is much more code.
 
What? The datawriter handles all of this? It isn't wrong to use REPLACE in certain situations, but it would be for specific situations which I doubt you actually need.
 
Are you reading from the database, or manipulating data retrieved from the database? Model.
Are you doing any writing to the database? Datawriter.

There are few exceptions.

It sounds like you'd want to do something like:
PHP:
$dw = XenForo_DataWriter::create('XenForo_DataWriter_Whatever');
$dw->setExistingData($data); // this can either be an array of an entire row, or the value of the primary key (usually id)
$dw->set('column', 'newValue');
$dw->save();
 
I use replace when I want to do very easy stuff like:

table car (car_id, owner_id) where car_id and owner_id are keys.

If a car has no owner, it is not even in the table. If a car gets an owner, I use REPLACE INTO car (2,5) to insert values (2,5). If the owner changes, I use REPLACE INTO car (2,6) to change values 2,5 to 2,6. Do you have an idea how you would accomplish that in the datawrater?
 
Here's a practical example for you.

PHP:
$writer = XenForo_DataWriter::create('YourAddOn_DataWriter_YourDataWriter');
 
$data = array(
	'car_id' => $carId,
	'owner_id' => $ownerId
);

$writer->setExistingData($carId);

$writer->bulkSet($data);

$writer->save;

This creates your DataWriter (this could be your own or an extended XenForo writer depending on its usage) and then defines the data. This assumes you've already got the data in a variable elsewhere in the function. You then tell the DataWriter that the existing record can be found using the $carId variable. Finally, the data is bulkSet (because it is in an array, if you're only updating a single value, you can just use "set") and then saved. Once $writer->save is run, the data is written.
 
Thanks! If car_id is NULL and on the same time car_id is primary or part of a unique key, is the datawriter intelligent enough to insert the data?
 
No. It will throw an exception. You should be doing...

if ($data['car_id'])
{
setExtingData here
}

You can see this pretty much in every spot a datawriter is used.
 
Let's roundup the datawriter method:

1. I have to check if car_id exists
2. If yes, I use setExistingData and save();
3. If no, I have to tell the datawriter it should create a new entry?

With replace, I just use $model->setMyreplace($dwData) and its fine. That looks much more elegant to me.
 
Well it is wrong. Simple. Unless there is a very specific reason to use REPLACE then you are doing it wrong.

Also you don't tell it to create, if it doesn't received a call from setExistingData it will automatically just create.

It also handles validation, security, pre and post events and probably most importantly is easily extended with add-ons.
 
We're missing a load of information that would help us ascertain the best way of doing things, but I can't personally think of many examples where using replace would be better.

But here's an example based on my notifications add-on.

I have a list of Notifications...
http://mysite.com/admin.php?notifications

I have an action to add new notifications:
http://mysite.com/admin.php?notifications/add

And an action to edit existing notifications, e.g. to edit notification with an ID of 1:
http://mysite.com/admin.php?notifications/1/edit

Whenever I am adding a new notification or editing an existing one, ultimately I end up at an action called "save", e.g.:
http://mysite.com/admin.php?notifications/save

So, in my template where I edit the details of a notification (either new or existing) my form action will look like:
<form action="{xen:adminlink 'notifications/save', $notification}" method="post"> ... </form>

If it's an existing notification (i.e. if $notification contains data) the action will be:
http://mysite.com/admin.php?notifications/1/save

If it's a new notification (i.e. if $notification contains no data) the action will be:
http://mysite.com/admin.php?notifications/save

So... finally my Save action in PHP looks like this:

PHP:
public function actionSave()
{
	$notificationId = $this->_input->filterSingle('notification_id', XenForo_Input::UINT);
	// This pulls the notificationId out of the requested URL, e.g. if it's an existing notification then $notificationId will now contain 1

	$data = $this->_input->filter(array(
		'name' => XenForo_Input::STRING,
		'other_data' => XenForo_Input::STRING
	));

	$writer = XenForo_DataWriter::create('Notifications_DataWriter_Notification');

	if ($notificationId)
	{
		$writer->setExistingData($notificationId);
	}
	// So, if notificationId exists, tell DataWriter to find the existing data.

	$writer->bulkSet($data);

	$writer->save();

	return $this->responseRedirect(
		XenForo_ControllerResponse_Redirect::SUCCESS,
		XenForo_Link::buildAdminLink('notifications/edit', $notificationId)
	);
}
 
Top Bottom