I am applying a regular membership inside a DB. The e-mail should be unique, so I've got a UNIQUE index within the database. I've this code during my page init:

$f = $p->add('MVCForm');
$f->setModel('Account',array('name','surname','email'));
$f->elements['Save']->setLabel('Subscribe');

if($f->isSubmitted())
{
    try
    {
         $f->update();

         //More useful code to execute when all is ok :)

    }
    catch(Exception_ValidityCheck $v)
    {
        //Handles validity constraint from the model
        $f->getElement($v->getField())->displayFieldError($v->getMessage());
    }
    catch(SQLException $se)
    {
        //If I'm here there is a problem with the db/query or a duplicate email
    }
}

The only real information in SQLException is really a formatted HTML message, is the only method to identify when the error comes from a copied entry?

Here is an excellent method to get it done:

https://github.com/atk4/atk4-web/blob/master/lib/Model/ATK/User.php#L95

Although if you wish to perform custom action on duplication, you need to move getBy outdoors from the model, into page's logic.

As @Col recommended, you want to use "place ignore".

$form->update() depends on Model->update() which in turn depends on DSQL class for building query. DSQL does support options, but model would generate fresh SQL for you personally.

Model->dsql() develops a question for that Model. It may function with several "instances", where each instance includes a separate query. I do not particularly such as this approach and can add new model class, however it works for the time being.

Have a look here: https://github.com/atk4/atk4-addons/blob/master/mvc/Model/MVCTable.php#L933

insertRecord() function calls dsql('modify',false) several occasions to construct the query. The easiest factor you could do this, most likely, is:

function insertRecord($data=array()){
    $this->dsql('modify',false)->option('IGNORE');
    return parent::insertRecord($data);
}

after record is placed, Agile Toolkit will instantly make an effort to load recently added record. It'll, however, make use of the relevant conditions. I believe than if record is overlooked, you will get exception raised anyway. If at all possible, avoid exceptions inside your workflow. Exceptions are CPU intensive given that they capture backtrace.

The only method may be that you should redefine insertRecord completely. It isn't ideal, however it would permit you to perform a single query as if you want.

I favor to by hand look into the condition with loadBy (or getBy) since it takes model conditions and joins into consideration. For instance, you may have soft remove you are cooking even though MySQL key wouldn't allow you to enter, Model would and also the model-way will work better too for business logic.

Why not wish to run simple choose to see if email has already been taken?

Or allow it to be Place IGNORE after which check affected_rows