Full-service Internet Marketing & Web Development
Recent Posts

Recommended Reads
|
How to fix Mercurial Corrupt RepositoryLiviu Olos, January 7 -- Posted under Programming |
If you're using Mercurial HG and keep running into the "premature EOF reading chunk" error, there's hope. As part of this post, I will walk you through the process of repairing a damaged repository where HG .i files are corrupt and no one can successfully "Pull Changes".
Step 1: Connect to your HG server, cd to the repository folder and run
If you get something like
Voila, you're dealing with HG index corruption.
Step 2: Backup the file path_to_project/.hg/store/data/error_file_name.extension.i backup/error_file_name.extension.i
Step 3: In the path_to_project/ folder create a new empty file
Step 4:
Step 5:
You might need to do hg commit -u hg_user_name
Step 6: Go to path_to_project/.hg/store/data/ and
This will replace the current file
Step 7: Pull the files from your local HG client and you should be all set!
-
Tip: To avoid unnecessary merges, always "Pull Changes" - "Commit" and "Push" as close to each other as possible.
Step 1: Connect to your HG server, cd to the repository folder and run
hg verify
If you get something like
Quote:
|
error_file_name.extension@553: unpacking 646ac1c08e97: ./../Objects/stringobject.c:4124: bad argument to internal function 10662 files, 567 changesets, 11475 total revisions 1 integrity errors encountered! |
Voila, you're dealing with HG index corruption.
Step 2: Backup the file path_to_project/.hg/store/data/error_file_name.extension.i backup/error_file_name.extension.i
Step 3: In the path_to_project/ folder create a new empty file
echo "" >> new_file.extension
Step 4:
hg add new_file.extension
Step 5:
hg commit
You might need to do hg commit -u hg_user_name
Step 6: Go to path_to_project/.hg/store/data/ and
cp new_file.extension.i error_file_name.extension.i
This will replace the current file
Step 7: Pull the files from your local HG client and you should be all set!
-
Tip: To avoid unnecessary merges, always "Pull Changes" - "Commit" and "Push" as close to each other as possible.
|
iContact 2.0 API Integration PHP ExampleMike Peters, December 25, 2009 -- Posted under Programming |
One of the cool features of SPI's Autoresponder service, is its ability to seamlessly integrate with third party autoresponders.
Once you designate an autoresponder as a third-party one, SPI will continue applying your predefined rules for adding/removing members from that autoresponder, while notifying the third-party service (GetResponse, iContact, AWeber) automatically.
Over the last few days, we have battling with iContact's new API. iContact announced their 2.0 API back on February 2009, but it's still labeled as "beta" and there's little to no documentation available online.
The SPI-iContact integration was using version 1.0 and our intention was to continue using that version until 2.0 is officially released.
Unfortunately, with no prior warning, version 1.0 stopped working and is no longer honoring requests to add contacts / subscriptions records.
iContact's API external login page is down. The help section is down:

And the developer forums are ghost town USA.

Ok, rant over.
We really like the folks at iContact. They offer an easy to use and inexpensive entry-level autoresponder service. I just wish they would update the API documentation.
The purpose of this post is to help others who are going through integrating with the iContact 2.0 API by providing simple PHP examples for adding a contract, subscripting a contact to a list and unsubscribing.
We haven't been able to find anything like this online, so I'm pretty sure this will help others going through the integration process.
The code below is self-contained. No need to use any other libraries.
function IContactLogin($account_id, $key, $user, $pass, &$client_folder_id)
{
// Build iContact authentication
$headers = array(
'Accept: text/xml',
'Content-Type: text/xml',
'Api-Version: 2.0',
'Api-AppId: ' . $key,
'Api-Username: ' . $user,
'Api-Password: ' . $pass
);
// Connect to iContact to retrieve the client folder id
$ch=curl_init("https://app.icontact.com/icp/a/$account_id/c/");
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$buf = curl_exec($ch);
curl_close($ch);
// Extract client folder id from response
$client_folder_id = "";
if (($pos=strpos($buf,"<clientFolderId>"))!==false)
{
$client_folder_id = substr($buf, strlen("<clientFolderId>")+$pos);
if (($pos=strpos($client_folder_id,"<"))!==false)
{
$client_folder_id = substr($client_folder_id, 0, $pos);
}
}
// If we have a non empty client_folder_id,
// then everything worked well
$result = ($client_folder_id+0 > 0);
// Return result
return $result;
}
function IContactSubscribe($account_id, $key, $user, $pass, $email, $list_id, &$result_str)
{
// Get client folder id
if (!IContactLogin($account_id, $key, $user, $pass, &$client_folder_id))
{
$result_str = "Failed retrieving client_folder_id for '$user'";
return 0;
}
// Build iContact authentication
$headers = array(
'Accept: text/xml',
'Content-Type: text/xml',
'Api-Version: 2.0',
'Api-AppId: ' . $key,
'Api-Username: ' . $user,
'Api-Password: ' . $pass
);
// Find contact_id for the given 'email'
$ch=curl_init("https://app.icontact.com/icp/a/$account_id/c/$client_folder_id/contacts/?email=".URLEncode($email));
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$buf = curl_exec($ch);
curl_close($ch);
// Extract contactId from response
$contact_id = "";
if (($pos=strpos($buf,"<contactId>"))!==false)
{
$contact_id = substr($buf, $pos+strlen("<contactId>"));
if (($pos=strpos($contact_id,"<"))!==false)
{
$contact_id = substr($contact_id,0,$pos);
}
}
// If we don't have a contactId, can't add subscription
if (empty($contact_id))
{
$result_str = "Failed finding a contact with the email address of '$email'";
return 0;
}
// Build subscription record
$data = '<?xml version="1.0" encoding="UTF-8"?>'."\r\n<subscriptions>\r\n";
$data.= "<subscription>\r\n";
$data.= "<contactId>$contact_id</contactId>\r\n";
$data.= "<listId>$list_id</listId>\r\n";
$data.= "<status>normal</status>\r\n";
$data.= "</subscription>\r\n</subscriptions>";
// Add subscription
$ch=curl_init("https://app.icontact.com/icp/a/$account_id/c/$client_folder_id/subscriptions/");
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$buf = curl_exec($ch);
curl_close($ch);
// Extract subscriptionID from response
$subscription_id = "";
if (($pos=strpos($buf,"<subscriptionId>"))!==false)
{
$subscription_id = substr($buf, $pos+strlen("<subscriptionId>"));
if (($pos=strpos($subscription_id,"<"))!==false)
{
$subscription_id = substr($subscription_id,0,$pos);
}
}
// If we have a subscription id OR this subscription already existed, we're good
$result = !empty($subscription_id) || strpos($buf,"could not be updated")!==false;
// Set result string
$result_str = ($result ? "Updated subscription $subscription_id" : $buf);
// Return result
return $result;
}
function IContactAddContact($account_id, $key, $user, $pass, $email, $firstname, $lastname,
&$result_str)
{
// Get client folder id
if (!IContactLogin($account_id, $key, $user, $pass, &$client_folder_id))
{
$result_str = "Failed retrieving client_folder_id for '$user'";
return 0;
}
// Build iContact authentication
$headers = array(
'Accept: text/xml',
'Content-Type: text/xml',
'Api-Version: 2.0',
'Api-AppId: ' . $key,
'Api-Username: ' . $user,
'Api-Password: ' . $pass
);
// Build contact record
$data = '<?xml version="1.0" encoding="UTF-8"?>'."\r\n<contacts>\r\n";
$data.= "<contact>\r\n";
$data.= "<email>$email</email>\r\n";
$data.= "<firstName>$firstname</firstName>\r\n";
$data.= "<lastName>$lastname</lastName>\r\n";
$data.= "<status>normal</status>\r\n";
$data.= "</contact>\r\n</contacts>";
// Add contact
$ch=curl_init("https://app.icontact.com/icp/a/$account_id/c/$client_folder_id/contacts/");
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$buf = curl_exec($ch);
curl_close($ch);
// Extract contactId from response
$contact_id = "";
if (($pos=strpos($buf,"<contactId>"))!==false)
{
$contact_id = substr($buf, $pos+strlen("<contactId>"));
if (($pos=strpos($contact_id,"<"))!==false)
{
$contact_id = substr($contact_id,0,$pos);
}
}
// If we have a contact id, we're good
$result = !empty($contact_id);
// Set result string
$result_str = ($result ? "Added new contact $contact_id" : $buf);
// Return result
return $result;
}
function IContactUnsubscribe($account_id, $key, $user, $pass, $email, $list_id, &$result_str)
{
// Get client folder id
if (!IContactLogin($account_id, $key, $user, $pass, &$client_folder_id))
{
$result_str = "Failed retrieving client_folder_id for '$user'";
return 0;
}
// Build iContact authentication
$headers = array(
'Accept: text/xml',
'Content-Type: text/xml',
'Api-Version: 2.0',
'Api-AppId: ' . $key,
'Api-Username: ' . $user,
'Api-Password: ' . $pass
);
// Find contact_id for the given 'email'
$ch=curl_init("https://app.icontact.com/icp/a/$account_id/c/$client_folder_id/contacts/?email=".URLEncode($email));
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$buf = curl_exec($ch);
curl_close($ch);
// Extract contactId from response
$contact_id = "";
if (($pos=strpos($buf,"<contactId>"))!==false)
{
$contact_id = substr($buf, $pos+strlen("<contactId>"));
if (($pos=strpos($contact_id,"<"))!==false)
{
$contact_id = substr($contact_id,0,$pos);
}
}
// If we don't have a contactId, can't add subscription
if (empty($contact_id))
{
$result_str = "Failed finding a contact with the email address of '$email'";
return 0;
}
// Build subscription record
$data = '<?xml version="1.0" encoding="UTF-8"?>'."\r\n<subscriptions>\r\n";
$data.= "<subscription>\r\n";
$data.= "<contactId>$contact_id</contactId>\r\n";
$data.= "<listId>$list_id</listId>\r\n";
$data.= "<status>unsubscribed</status>\r\n";
$data.= "</subscription>\r\n</subscriptions>";
// Add subscription
$ch=curl_init("https://app.icontact.com/icp/a/$account_id/c/$client_folder_id/subscriptions/");
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$buf = curl_exec($ch);
curl_close($ch);
// Extract subscriptionID from response
$subscription_id = "";
if (($pos=strpos($buf,"<subscriptionId>"))!==false)
{
$subscription_id = substr($buf, $pos+strlen("<subscriptionId>"));
if (($pos=strpos($subscription_id,"<"))!==false)
{
$subscription_id = substr($subscription_id,0,$pos);
}
}
// If we have a subscription id OR this subscription already unsubscribed, we're good
$result = !empty($subscription_id) || strpos($buf,"could not be updated")!==false;
// Set result string
$result_str = ($result ? "Updated subscription $subscription_id" : $buf);
// Return result
return $result;
}
View 3 Comment(s)
Once you designate an autoresponder as a third-party one, SPI will continue applying your predefined rules for adding/removing members from that autoresponder, while notifying the third-party service (GetResponse, iContact, AWeber) automatically.
Over the last few days, we have battling with iContact's new API. iContact announced their 2.0 API back on February 2009, but it's still labeled as "beta" and there's little to no documentation available online.
The SPI-iContact integration was using version 1.0 and our intention was to continue using that version until 2.0 is officially released.
Unfortunately, with no prior warning, version 1.0 stopped working and is no longer honoring requests to add contacts / subscriptions records.
iContact's API external login page is down. The help section is down:

And the developer forums are ghost town USA.

Ok, rant over.
We really like the folks at iContact. They offer an easy to use and inexpensive entry-level autoresponder service. I just wish they would update the API documentation.
The purpose of this post is to help others who are going through integrating with the iContact 2.0 API by providing simple PHP examples for adding a contract, subscripting a contact to a list and unsubscribing.
We haven't been able to find anything like this online, so I'm pretty sure this will help others going through the integration process.
The code below is self-contained. No need to use any other libraries.
function IContactLogin($account_id, $key, $user, $pass, &$client_folder_id)
{
// Build iContact authentication
$headers = array(
'Accept: text/xml',
'Content-Type: text/xml',
'Api-Version: 2.0',
'Api-AppId: ' . $key,
'Api-Username: ' . $user,
'Api-Password: ' . $pass
);
// Connect to iContact to retrieve the client folder id
$ch=curl_init("https://app.icontact.com/icp/a/$account_id/c/");
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$buf = curl_exec($ch);
curl_close($ch);
// Extract client folder id from response
$client_folder_id = "";
if (($pos=strpos($buf,"<clientFolderId>"))!==false)
{
$client_folder_id = substr($buf, strlen("<clientFolderId>")+$pos);
if (($pos=strpos($client_folder_id,"<"))!==false)
{
$client_folder_id = substr($client_folder_id, 0, $pos);
}
}
// If we have a non empty client_folder_id,
// then everything worked well
$result = ($client_folder_id+0 > 0);
// Return result
return $result;
}
function IContactSubscribe($account_id, $key, $user, $pass, $email, $list_id, &$result_str)
{
// Get client folder id
if (!IContactLogin($account_id, $key, $user, $pass, &$client_folder_id))
{
$result_str = "Failed retrieving client_folder_id for '$user'";
return 0;
}
// Build iContact authentication
$headers = array(
'Accept: text/xml',
'Content-Type: text/xml',
'Api-Version: 2.0',
'Api-AppId: ' . $key,
'Api-Username: ' . $user,
'Api-Password: ' . $pass
);
// Find contact_id for the given 'email'
$ch=curl_init("https://app.icontact.com/icp/a/$account_id/c/$client_folder_id/contacts/?email=".URLEncode($email));
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$buf = curl_exec($ch);
curl_close($ch);
// Extract contactId from response
$contact_id = "";
if (($pos=strpos($buf,"<contactId>"))!==false)
{
$contact_id = substr($buf, $pos+strlen("<contactId>"));
if (($pos=strpos($contact_id,"<"))!==false)
{
$contact_id = substr($contact_id,0,$pos);
}
}
// If we don't have a contactId, can't add subscription
if (empty($contact_id))
{
$result_str = "Failed finding a contact with the email address of '$email'";
return 0;
}
// Build subscription record
$data = '<?xml version="1.0" encoding="UTF-8"?>'."\r\n<subscriptions>\r\n";
$data.= "<subscription>\r\n";
$data.= "<contactId>$contact_id</contactId>\r\n";
$data.= "<listId>$list_id</listId>\r\n";
$data.= "<status>normal</status>\r\n";
$data.= "</subscription>\r\n</subscriptions>";
// Add subscription
$ch=curl_init("https://app.icontact.com/icp/a/$account_id/c/$client_folder_id/subscriptions/");
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$buf = curl_exec($ch);
curl_close($ch);
// Extract subscriptionID from response
$subscription_id = "";
if (($pos=strpos($buf,"<subscriptionId>"))!==false)
{
$subscription_id = substr($buf, $pos+strlen("<subscriptionId>"));
if (($pos=strpos($subscription_id,"<"))!==false)
{
$subscription_id = substr($subscription_id,0,$pos);
}
}
// If we have a subscription id OR this subscription already existed, we're good
$result = !empty($subscription_id) || strpos($buf,"could not be updated")!==false;
// Set result string
$result_str = ($result ? "Updated subscription $subscription_id" : $buf);
// Return result
return $result;
}
function IContactAddContact($account_id, $key, $user, $pass, $email, $firstname, $lastname,
&$result_str)
{
// Get client folder id
if (!IContactLogin($account_id, $key, $user, $pass, &$client_folder_id))
{
$result_str = "Failed retrieving client_folder_id for '$user'";
return 0;
}
// Build iContact authentication
$headers = array(
'Accept: text/xml',
'Content-Type: text/xml',
'Api-Version: 2.0',
'Api-AppId: ' . $key,
'Api-Username: ' . $user,
'Api-Password: ' . $pass
);
// Build contact record
$data = '<?xml version="1.0" encoding="UTF-8"?>'."\r\n<contacts>\r\n";
$data.= "<contact>\r\n";
$data.= "<email>$email</email>\r\n";
$data.= "<firstName>$firstname</firstName>\r\n";
$data.= "<lastName>$lastname</lastName>\r\n";
$data.= "<status>normal</status>\r\n";
$data.= "</contact>\r\n</contacts>";
// Add contact
$ch=curl_init("https://app.icontact.com/icp/a/$account_id/c/$client_folder_id/contacts/");
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$buf = curl_exec($ch);
curl_close($ch);
// Extract contactId from response
$contact_id = "";
if (($pos=strpos($buf,"<contactId>"))!==false)
{
$contact_id = substr($buf, $pos+strlen("<contactId>"));
if (($pos=strpos($contact_id,"<"))!==false)
{
$contact_id = substr($contact_id,0,$pos);
}
}
// If we have a contact id, we're good
$result = !empty($contact_id);
// Set result string
$result_str = ($result ? "Added new contact $contact_id" : $buf);
// Return result
return $result;
}
function IContactUnsubscribe($account_id, $key, $user, $pass, $email, $list_id, &$result_str)
{
// Get client folder id
if (!IContactLogin($account_id, $key, $user, $pass, &$client_folder_id))
{
$result_str = "Failed retrieving client_folder_id for '$user'";
return 0;
}
// Build iContact authentication
$headers = array(
'Accept: text/xml',
'Content-Type: text/xml',
'Api-Version: 2.0',
'Api-AppId: ' . $key,
'Api-Username: ' . $user,
'Api-Password: ' . $pass
);
// Find contact_id for the given 'email'
$ch=curl_init("https://app.icontact.com/icp/a/$account_id/c/$client_folder_id/contacts/?email=".URLEncode($email));
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$buf = curl_exec($ch);
curl_close($ch);
// Extract contactId from response
$contact_id = "";
if (($pos=strpos($buf,"<contactId>"))!==false)
{
$contact_id = substr($buf, $pos+strlen("<contactId>"));
if (($pos=strpos($contact_id,"<"))!==false)
{
$contact_id = substr($contact_id,0,$pos);
}
}
// If we don't have a contactId, can't add subscription
if (empty($contact_id))
{
$result_str = "Failed finding a contact with the email address of '$email'";
return 0;
}
// Build subscription record
$data = '<?xml version="1.0" encoding="UTF-8"?>'."\r\n<subscriptions>\r\n";
$data.= "<subscription>\r\n";
$data.= "<contactId>$contact_id</contactId>\r\n";
$data.= "<listId>$list_id</listId>\r\n";
$data.= "<status>unsubscribed</status>\r\n";
$data.= "</subscription>\r\n</subscriptions>";
// Add subscription
$ch=curl_init("https://app.icontact.com/icp/a/$account_id/c/$client_folder_id/subscriptions/");
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$buf = curl_exec($ch);
curl_close($ch);
// Extract subscriptionID from response
$subscription_id = "";
if (($pos=strpos($buf,"<subscriptionId>"))!==false)
{
$subscription_id = substr($buf, $pos+strlen("<subscriptionId>"));
if (($pos=strpos($subscription_id,"<"))!==false)
{
$subscription_id = substr($subscription_id,0,$pos);
}
}
// If we have a subscription id OR this subscription already unsubscribed, we're good
$result = !empty($subscription_id) || strpos($buf,"could not be updated")!==false;
// Set result string
$result_str = ($result ? "Updated subscription $subscription_id" : $buf);
// Return result
return $result;
}
View 3 Comment(s)
|
How to run SSH on a different portMike Peters, December 21, 2009 -- Posted under Programming |
By default SSH runs on port 22. One of the easiest ways to make it more difficult for hackers to run dictionary attacks on your server, attempting to brute-force ssh-login, is to run ssh on a different port.
Open up /etc/ssh/sshd_config and add this line at the top:
Replace 1234 with the port number you'd like to run ssh on. If there is already a Port line in your sshd_config file, comment it with a #
Now, Restart sshd by issuing:
Test ssh works properly by connecting locally (replace 1234 with the new port number):
View 1 Comment(s)
Open up /etc/ssh/sshd_config and add this line at the top:
Port 1234
Replace 1234 with the port number you'd like to run ssh on. If there is already a Port line in your sshd_config file, comment it with a #
Now, Restart sshd by issuing:
/etc/rc.d/init.d/sshd restart
Test ssh works properly by connecting locally (replace 1234 with the new port number):
ssh -l USERNAME localhost -p 1234
View 1 Comment(s)
|
MapReduce 101: Parallel ProgrammingMike Peters, December 21, 2009 -- Posted under Programming |
Two of the best video tutorials explaining the basics of MapReduce.
If you're used to MySQL, you can think of "Map" as several queries running "SELECT" where data is extracted from multiple tables. And you can think of "Reduce" as the "GROUP BY" operator where data is joined together to form a short result.
For more information about MapReduce, see Google's Introduction to Parallel Programming and MapReduce
If you're used to MySQL, you can think of "Map" as several queries running "SELECT" where data is extracted from multiple tables. And you can think of "Reduce" as the "GROUP BY" operator where data is joined together to form a short result.
For more information about MapReduce, see Google's Introduction to Parallel Programming and MapReduce
|
Never use VARCHAR in MySQLMike Peters, December 15, 2009 -- Posted under Programming |
When using strings in MySQL, you have a choice between several field types:
* VARCHAR: String of 0..65,535 characters with an extra byte to designate the length.
* CHAR: String of a fixed length of 0 to 255 characters.
* TEXT / BIGTEXT: String of 1..4GB characters with an extra byte to designate the length. Unlike VARCHAR, text fields cannot be compared, can't "order by", can't use "like" on them etc.
* BLOB: For binary or unicode strings. Supports 8bits per character and unlike the previous types, the string is not converted to a character-set prior to insertion.
Quick tip: Never ever use varchar.
Replace VARCHAR with CHAR whenever possible, or use TEXT if your strings are longer than 255 characters.
While VARCHAR offers slightly improved storage space (it will only take up n+1 characters on disk), there are a few major pitfalls with this variable type:
#1. If you have any field in the table that is a CHAR (fixed size) field, all VARCHARs will be stored as n+1, so you don't get any reduced storage benefits.
#2. If you're using MySQL replication, you may end up with a few nasty "master/slave table column type mismatch" errors - this is a big one
#3. CHAR fields offer better performance over VARCHAR
-
We first learned about the issues with VARCHAR when replication began breaking with these cryptic messages:
"Table definition on master and slave does not match: Column 37 size mismatch - master has size 255, testtable on slave has size 256. Master's column size should be <= the slave's column size."
Both tables were identical and mysqldump'ing one on top of the other didn't help. It seems to be rooted to MySQL's internal implementation of VARCHAR.
To convert all table VARCHAR fields to CHAR, use this PHP snippet:
* VARCHAR: String of 0..65,535 characters with an extra byte to designate the length.
* CHAR: String of a fixed length of 0 to 255 characters.
* TEXT / BIGTEXT: String of 1..4GB characters with an extra byte to designate the length. Unlike VARCHAR, text fields cannot be compared, can't "order by", can't use "like" on them etc.
* BLOB: For binary or unicode strings. Supports 8bits per character and unlike the previous types, the string is not converted to a character-set prior to insertion.
Quick tip: Never ever use varchar.
Replace VARCHAR with CHAR whenever possible, or use TEXT if your strings are longer than 255 characters.
While VARCHAR offers slightly improved storage space (it will only take up n+1 characters on disk), there are a few major pitfalls with this variable type:
#1. If you have any field in the table that is a CHAR (fixed size) field, all VARCHARs will be stored as n+1, so you don't get any reduced storage benefits.
#2. If you're using MySQL replication, you may end up with a few nasty "master/slave table column type mismatch" errors - this is a big one
#3. CHAR fields offer better performance over VARCHAR
-
We first learned about the issues with VARCHAR when replication began breaking with these cryptic messages:
"Table definition on master and slave does not match: Column 37 size mismatch - master has size 255, testtable on slave has size 256. Master's column size should be <= the slave's column size."
Both tables were identical and mysqldump'ing one on top of the other didn't help. It seems to be rooted to MySQL's internal implementation of VARCHAR.
To convert all table VARCHAR fields to CHAR, use this PHP snippet:
@mysql_query("SET GLOBAL WAIT_TIMEOUT = 600000");
@mysql_Query("SET WAIT_TIMEOUT = 600000");
$Result1 = @mysql_query("SHOW TABLES FROM $DBNAME");
$cnt1 = @mysql_num_rows($Result1);
while ($cnt1)
{
$cnt1--;
if (!($Row1 = @mysql_fetch_array($Result1)))
{
continue;
}
$tablename = $Row1[0];
$Result3 = @mysql_query("DESCRIBE $tablename");
$cnt3 = @mysql_num_rows($Result3);
while ($cnt3)
{
$cnt3--;
if (!($Row3 = @mysql_fetch_array($Result3))) continue;
if (strpos($Row3['Type'],'varchar')!==false)
{
$pos = strpos($Row3['Type'],'(');
$length = substr($Row3['Type'],$pos+1);
$pos = strpos($length,')');
$length = substr($length, 0, $pos);
// If length is over 255, nothing we can do about it
if ($length>255) continue;
if ($length<1) continue;
// Length is below 255, we can convert
$sql = "alter table $tablename change ".$Row3['Field']." ".$Row3['Field']." char($length) default '' not null";
@mysql_query($sql);
}
}
}
@mysql_Query("SET WAIT_TIMEOUT = 600000");
$Result1 = @mysql_query("SHOW TABLES FROM $DBNAME");
$cnt1 = @mysql_num_rows($Result1);
while ($cnt1)
{
$cnt1--;
if (!($Row1 = @mysql_fetch_array($Result1)))
{
continue;
}
$tablename = $Row1[0];
$Result3 = @mysql_query("DESCRIBE $tablename");
$cnt3 = @mysql_num_rows($Result3);
while ($cnt3)
{
$cnt3--;
if (!($Row3 = @mysql_fetch_array($Result3))) continue;
if (strpos($Row3['Type'],'varchar')!==false)
{
$pos = strpos($Row3['Type'],'(');
$length = substr($Row3['Type'],$pos+1);
$pos = strpos($length,')');
$length = substr($length, 0, $pos);
// If length is over 255, nothing we can do about it
if ($length>255) continue;
if ($length<1) continue;
// Length is below 255, we can convert
$sql = "alter table $tablename change ".$Row3['Field']." ".$Row3['Field']." char($length) default '' not null";
@mysql_query($sql);
}
}
}
|
How to Flush DNSMike Peters, December 6, 2009 -- Posted under Programming |
At times you want to force your machine to "forget" (flush) all DNS entries, so that it reloads any recent changes.
This is useful when you've recently updated the ip-address of a domain and want your machine to see the new changes, without relying on any previously stored cache.
Here's how to flush your DNS cache:
Windows
Open a CMD dos box and run:
ipconfig /flushdns
If you get an error about "this requires elevation", do this: Click on the Windows Start button, type "cmd", then right click on the program and select "Run as Administrator"
Mac
In Mac OSX Leopard, you can use the command
dscacheutil to flush the DNS resolver cache:
dscacheutil -flushcache
In Mac OSX versions 10.5.1 and before, the command lookupd -flushcache performed the same task:
lookupd -flushcache
Linux
In Linux, the nscd daemon manages the DNS cache.
To flush the DNS cache, restart the nscd daemon.
To restart the nscd daemon, use the command:
/etc/init.d/nscd restart
This is useful when you've recently updated the ip-address of a domain and want your machine to see the new changes, without relying on any previously stored cache.
Here's how to flush your DNS cache:
Windows
Open a CMD dos box and run:
ipconfig /flushdns
If you get an error about "this requires elevation", do this: Click on the Windows Start button, type "cmd", then right click on the program and select "Run as Administrator"
Mac
In Mac OSX Leopard, you can use the command
dscacheutil to flush the DNS resolver cache:
dscacheutil -flushcache
In Mac OSX versions 10.5.1 and before, the command lookupd -flushcache performed the same task:
lookupd -flushcache
Linux
In Linux, the nscd daemon manages the DNS cache.
To flush the DNS cache, restart the nscd daemon.
To restart the nscd daemon, use the command:
/etc/init.d/nscd restart
| « Previous Posts | » Next Posts |
