creating my own save command in cakephp - mysql

As we all know that cakephp has default save command for inserting record into the database.
But i want to know can i create my own save command in cakephp or modify the existing one.
Can I do this?
You must be asking why i'm asking why i'm saying that? let me give you an live example for this----
Suppose i have an textbox which contains the username entered by the user.I'm not taking this as unique, hence more than one user will insert same username(possible..).
Ex-My name is prakash Gupta and i'm taking the username 'prakash'. There will be other users also whose name can be prakash gupta and they will provide the same username.Now inorder to solve this i'm using random function and attaching some digits behind the username, so that
it will be different for every one.
Now 'save' command will take the username which i entered in the textbox and insert into the database but i want to insert the modified username into the database which i generated
by random function. can this be possible???
if yes let me know....

Normally you don't change the standard one but either add another one or use the beforeSave etc. hooks.
The save functions are part of the Models. Normally you modify them with: Behaviors. See: http://book.cakephp.org/2.0/en/models/behaviors.html They let you modify the models, saving etc. without having to code all directly into your models.
Based on your edit:
Unique constraint
As I see you want a unique username. There are multiple solutions for that. First make sure to set a constraint. Even your random() trick will possibly generate a duplicate since random can create also the same. So username.random(4) could generate multiple times: username1234. You cannot be sure.
Constraints should be set at for example your model level. Start this unique check with validations of CakePHP.
When do you know the username is already used
You will know when the validation failed. So first just validate the record. So before save call model::validate() to check whether your unique constraint is ok. If yes just save.
http://book.cakephp.org/2.0/en/models/data-validation.html
If not you can add your random string and check again. Call model::validate to see if it is now ok. This part could be implemented for example in a behaviour in the beforeSave() method.
Now you have a unique one save your record. Make sure to check whether it succeeded because it is possible that in the meantime another record with that username was added. In that case re-run the process.
Lots of work
It is hard because multiple clients can add data same time in a database before you even know. Most simple is to catch the error, so just call save with your username. If it fails because of your unique constraint add the random() string and try again and again. It should be possible to save. Trick here with your random string because if it is short and a username is used a lot you can run into issues. If your random string is 3 numbers you can have the same username 1000 times, from 000 to 999.
Other option
What you sometimes see is suggestions, the interface suggests some free names based on your username input. You still need the check though.
Another option
Just tell the user it is in use. Maybe add an ajax check so you can instantly show the result by validating the field.

Related

Is it possible to create DDL table where specific attribute has to end with digit?

I'm new to MySQL.
I'm trying to create table "Customer" with attribute "Password".
I'd like to know is it possible in DDL to make a constraint,that password has to contain 5 chars, while the last one is digit(one of this: 0-9)
I have tried to search for the answer, but could not find one.
I'm pretty sure that I cant satisfy this condition, but I will be glad to hear an oponion of someone who understands better then me.
Thank you!
Your requirement should never be an actual consideration, because you should not be storing clear text passwords in your MySQL database in the first place. Instead, you should be checking password creation in your PHP server code (as well as possibly on the front end). If valid, you should be hashing your passwords irreversibly, and then storing the hash in the user table. Your exact specified requirements can be gotten using the following regex pattern:
^.{4,}\d$
This would match 5 or more characters of any kind, the last of which is a digit. For some more ideas on a better password strength, and how to write a regex for that, consider reading the canonical SO question
Regex to validate password strength.
Edit:
Given that it appears you are using SQL Server, if you really needed a clear text password column with your requirements, you could use a check constraint:
CREATE TABLE users (
id INT NOT NULL,
password VARCHAR(100) NOT NULL,
CONSTRAINT check_password
CHECK (LEN(password) >= 5 AND RIGHT(password, 1) LIKE '[0-9]')
);
Why not make a PHP page for the entries and place all restrictions on that page?
As in MySql, you can't have so many restrictions.
You can also sue MySql procedure for inserting values and place restrictions from there.

Perl MySQL - How do I skip updating or inserting a row if a particular field matches?

I am pretty new to this so sorry for my lack of knowledge.
I set up a few tables which I have successfully written to and and accessed via a Perl script using CGI and DBI modules thanks to advice here.
This is a member list for a local band newsletter. Yeah I know, tons of apps out there but, I desire to learn this.
1- I wanted to avoid updating or inserting a row if an piece of my input matches column data in one particular column/field.
When creating the table, in phpmyadmin, I clicked the "U" (unique) on that columns name in structure view.
That seemed to work and no dupes are inserted but, I desire a hard coded Perl solution so, I understand the mechanics of this.
I read up on "insert ignore" / "update ignore" and searched all over but, everything I found seems to not just skip a dupe.
The column is not a key or autoinc just a plain old field with an email address. (mistake?)
2- When I write to the database, I want to do NOTHING if the incoming email address matches one in that field.
I desire the fastest method so I can loop through their existing lists export data, (they cannot figure out the software) with no racing / locking issues or whatever conditions in which I am in obvious ignorance.
Since I am creating this from scratch, 1 and 2 may be in fact partially moot. If so, what would be the best approach?
I would still like an auto increment ID so, I can access via the ID number or loop through with some kind of count++ foreach.
My stone knife approach may be laughable to the gurus here but, I need to start somewhere.
Thanks in advance for your assistance.
With the email address column declared UNIQUE, INSERT IGNORE is exactly what you want for insertion. Sounds like you already know how to do the right thing!
(You could perform the "don't insert if it already exists" functionality in perl, but it's difficult to get right, because you have to wrap the test and update in a transaction. One of the big advantages of a relational database is that it will perform constraint checks like this for you, ensuring data integrity even if your application is buggy.)
For updating, I'm not sure what an "update ignore" would look like. What is in the WHERE clause that is limiting your UPDATE to only affect the 1 desired row? Perhaps that auto_increment primary key you mentioned? If you are wanting to write, for example,
UPDATE members SET firstname='Sue' WHERE member_id = 5;
then I think this "update ignore" functionality you want might just be something like
UPDATE members SET firstname='Sue' WHERE member_id = 5
AND email != 'sue#example.com';
which is an odd thing to do, but that's my best guess for what you might mean :)
Just do the insert, if data would make the unique column not be unique you'll get an SQL error, you should be able to trap this and do whatever is appropriate (e.g. ignore it, log it, alert user ...)

How can I add regular expressions to MySQL datafields?

I have the following table:
Table Account{
[...]
email varchar(100),
[...]
}
and a corresponding regular expression:
/^[A-Z0-9._%+-]+#[A-Z0-9.-]+\.[A-Z]{2,4}$/i
How can I use the MySQL model, to link the regular expression to the the data-field "email", so that the regex is accessible to read out through php as well as a trigger or even better, in a kind of constraint?
I want to define this directly using MySQL workbench, so a separate table won't work for me.
In my opinion, input validation like this is not really the task of the database. Those validation rules may change. You may even make them configurable by the user some day. This becomes awfully difficult if the rules are buried in some trigger somewhere.
Also, you will need to handle a validation error on application level anyway - showing a message of some sort.
The best place to make them accessible to PHP inside mySQL may be a column comment, that you can fetch using SHOW COLUMNS in conjunction with the FULL keyword.

get the next id

My question is how to get the next id using NHibernate in a mysql db for an auto-increment ID column ?
Thanks,
Based on the further description you give (as an answer?) below it seems to me that you are indeed looking for the NHibernate feature to automatically read back IDs generated by the database: identity
This will tell NHibernate the ID's value is determined by the database upon insert, it will not send a value as part of its INSERT statement and it will read back the value of the ID column after it has performed the insert. But you do have to tell the database (in the table definition) that it should auto-generate a value for the ID column for each record inserted...
You're going to create a race condition if you do this. To answer your question, I don't think there is a specific way for Hibernate to give you this information since no application can give you this information. By getting the "next id", by the time it returns that data to you, it might be invalid already. The easiest way I can think of is to get the last_insert_id() and add +1 to it.
Why don't you post more information about you're trying to accomplish and we can find a better solution for you?
Provided that you are the only writer to your database then you could get your application to maintain the sequence number for you and allocate the next number yourself.
If you want to do this then you'll want to ensure that your application counter is thread safe.
You'll also want a way to get the last written sequence number when restarting you application.

ms access can't edit field because I must delete relationships but there are no relationships to delete

I have built a database on multiple tables. One of these tables has a field (Initials) that was originally defined to have 50 characters. After building the entire thing I realize I would have liked that field to be limited to 3 characters. I tried to change this, but it tells me that I have to delete one or more relationships. So, I open up the relationship window and delete the one relationship that is attached to this field, expecting that I should be able to go back and change the character limit then go back and add the relationship again. So, as of now there are ABSOLUTELY NO relationships touching Initials in the relationships window. I go back to change the char limit and it gives me the same error. I can't even delete Initials and recreate it because of the same error. I went through my entire project and took that field out wherever it appeared. Still, same error. Any ideas?
Per Matt,
apparently when you display a field in a report it does not show up in the relationships >window. I deleted it from the report, edited the char limit, then put it back in the >project. of course, right when i resort to the forum i figure it out. thanks to those who >helped