Featured Posts

Apple Mail Encryption with GPGMail and OpenPGP I've dabbled with encryption several times over the past few decades, never really getting serious about it.  It started when, in college, I would see that the faculty...

Read more

1Password on Ubuntu 11.10 (Oneiric) First, I apologize for being off-the-grid for so long.  I recently started working for a new company and am deep in the throes of the start-up life.  I started working...

Read more

BuddyPress -- Pages failing to load (404) I was going insane working on a buddypress install for our intranet's tech-blog because every page I attempted to load into Wordpress following the Buddypress install...

Read more

BuddyPress -- Pages failing to load (404) I was going insane working on a buddypress install for our intranet's tech-blog because every page I attempted to load into Wordpress following the Buddypress install...

Read more

Renaming mongodb Columns Today I was putzing around in the geo-spatial collection when I noticed that I had an unhappy over one of the column names within the collection. In the mySQL world,...

Read more

Subscribe

Converting a mySQL Column to AutoIncrement

Category : Technical
No Gravatar

We’re updating a large dataset at work — there’s about an 18% increase in the number of tuples in the new dataset spread across a highly-normalized 8 or so tables.

I have to port the new data into a (more) efficient table structure — so I’m de-normalizing the heck out of the data reducing the schema from eight tables to a single table.

In the old architecture, four of the tables have unique key values that were imposed on the data during the original port.  So, to maintain application compatibility in the data catalog, these key values have to be maintained.  Additionally, new tuples of data have to be added to the data set and new (old) key values assigned.

In porting over one of the updated tables, which uses a string-code as the primary key, I first export the old table columns (pkey, str_code) into a temp table and then add an auto_increment int() column to the new table marking the column as default = null.  I then do a simple update-join to bring over the old pkey values based on the native str_code.

This leaves me with a new numeric column that has a variable number of NULL values (representing the delta of the new-data import) interspersed with the legacy data pkey -> str_code values.

The problem is: how do I convert the NULL pkey fields to a meaningful value that maintains the auto-increment without causing mysql to totally freak?

The first thing I do is get the max-value of the pkey:

select max(pkey_field_name) from table_name;
+---------------+
| max(pkey_...) |
+---------------+
|          4162 |
+---------------+
1 row in set (0.00 sec)

Next, I need to reset the auto_increment value of the column because, since the column is just a numeric column, it currently defaults to zero.  Attempting to convert the column on-the-fly to auto-increment will cause mysql to spit and error out about duplicate primary key values…

mysql> alter table table_name auto_increment=4163;
Query OK, 3965 rows affected (0.05 sec)
Records: 3965 Duplicates: 0 Warnings: 0

Now that I have the auto_increment reset, I can convert the column to auto_increment type and, in the process of converting, mySQL will re-number the NULL column key values using the new auto_increment value so that my numbering scheme is seamless.

When I query the data back, I can see that my new column is completely re-ordered with the legacy data maintained and the new data correctly keyed.

Resetting the auto-increment key is a handy little trick to know — I also use it when building test datasets and I need a fast way to reset my table values.

Hope this helps!

 

 

Note:  Here’s the complete and full steps to successfully complete this operation.

(DDL for admin1 table)

CREATE TABLE `admin1` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `field1` varchar(255) NOT NULL,
  `field2` varchar(255) NOT NULL,
  `field3` varchar(255) NOT NULL,
  `field4` varchar(255) NOT NULL,
  `field5` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=4163 DEFAULT CHARSET=utf8

(DDL for admin1ll table)

CREATE TABLE `admin1ll` (
  `field1` int(11) NOT NULL,
  `field2` varchar(255) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8

 

Step 1:  Create a new integer column in the table

ALTER TABLE `meridian`.`admin1` DROP COLUMN `id`, ADD COLUMN `id` int UNSIGNED FIRST, CHANGE COLUMN `field1` `field1` varchar(255) NOT NULL AFTER `id`, CHANGE COLUMN `field2` `field2` varchar(255) NOT NULL AFTER `field1`, CHANGE COLUMN `field3` `field3` varchar(255) NOT NULL AFTER `field2`, CHANGE COLUMN `field4` `field4` varchar(255) NOT NULL AFTER `field3`, CHANGE COLUMN `field5` `field5` varchar(255) NOT NULL AFTER `field4`;

Step 2:  Update the new column by inserting the previous-tables pkey values

update admin1, admin1ll
set admin1.id = admin1ll.field1
where admin1.field1 = admin1ll.field2

Step 3: Update the Auto_Increment value:

> select max(id) from admin1;

4030

> alter table admin1 auto_increment=4031;

Note:  the row count does not imply or set the auto_increment value!

Step 4: Reformat Column

Set column to auto_increment, unsignent, not null, primary key

Step 5:  Validate!

select *

from admin1, admin1ll

where admin1.id <> admin1ll.field1

and admin1.field1 = admin1ll.field2

> Empty set (1.70 sec)

HTC Thunderbolt – The Honeymoon? Definitely Over.

Category : Rant, Technical, WTF
No Gravatar

First, let me begin by saying that I have been an Apple fan for a long time. In addition to using their computers, I was a first generation adopter of both the iPod and the iPhone.  I’ve gone through the original iPhone, the 3G and the 4.

What I like about the iPhone can be summed up by saying that it represents exemplary engineering on top of a ghastly deployment.

After all those years of being an iPhone user with AT&T, I could no longer justify paying for AT&T’s sub-standard cellular services.  The times I could complete a conversation on my iPhone without dropping the call, or losing call quality was an extremely rare event.  (And I live in the Bay area, home to AT&T which is touted as one of their major coverage areas….)

AT&T’s cellular service is simply pathetic.  As a matter of fact, I deemed it justifiable to pay the contract cancellation penalty with AT&T to come to Verizon.  I never realized how bad AT&T service was, however, until switched to Verizon.   Within my first week of using my Thunderbolt, I experienced NO dropped calls, NO poor signals, NO service interruptions of any kind.  (Unless I was connected to an AT&T cellular customer…)

And, while Apple is, in my opinion, the best hardware engineer in the business, the other factor in my decision to move phone platforms was that Apple never quite got the whole synchronization thing down. (Pre-iCloud)  I really don’t need seven different listings for my veterinarian in my address book.  Syncing services with Google have been working for me perfectly – and I don’t have to pay them $99 per year to screw up my address book contents or my calendar.

So I dropped .me and my iPhone for a Google phone living in a Google world.  Since the Android requires a Google account, (Hey! I have one of those!), setting up my phone required that I only provide it with my account information and everything from that point was auto-magically configured for me.  Insta-integration with all my Google-based services.  Plus really cool stuff like Google Voice for messaging.

….

It’s now been six months with the Android. Apple has just released their iPhone 4S…and, within a day, I find myself browsing the provider’s pages looking/comparing contracts and service offerings.  What the hell am I doing?!?

The shine on this Android HTC Thunderbolt phone is definitely gone.  While I like most of the Verizon services, specifically the quality of the cellular coverage, I am really dissatisfied with some of their processes and, as far as the phone is concerned, the HTC Thunderbolt is a complete a total piece of crap.  I will NEVER, EVER buy another phone from HTC every again.

Problems with Verizon and the HTC Thunderbolt Nobody Talks About:

1. Crapware

I rooted my Android within a week of getting it.  Verizon pre-loaded the Thunderbolt with an amazing amount of crapware that they don’t allow you to delete off their phone.  Seriously bad software.  That does nothing except eat tons of space in my memory store.  Once I rooted the phone (similar to the jail-breaking process for the iPhone), I was able to delete that bloatware and regain my lost storage for other applications.

2. Say My Name, Bitch!

Of course there’s a problem with rooting your phone — and that’s dealing with Verizon’s never-ending attempts to force software updates down your throat and to your phone.  Should you make the tragic mistake of leaving your phone “on” (which I do when sitting at my desk with the phone plugged into the charger) then Verizon assumes control of your phone by forcing your phone to accept updates over the network.

Since you’ve rooted your phone, said updates (which are image zip files stored to your cache) will not install after the download completes and the phone reboots itself.  All without any confirmation or interaction from your part.  Special, no?

When your phone reboots, you’re presented with the broken-android symbol and you have to go into your root-tools menu to delete the cached files from your phone.  This removes the forced-download and allows you to reboot your phone into it’s previously rooted state.  Of course, leave your phone on for too long and here it comes again!

There’s no “off” switch to disable the forced downloads.  Verizon’s attitude, gleaned from the forums, is that: “It’s our network.  Suffer, bitch.”

3. Random Reboots and Disappearing Apps

My co-workers claim that my phone re-booting itself (without an “upgrade” being pushed down) is because I rooted my phone.  After reading the complaints about the HTC Thunderbolt out on the etherstream – I beg to differ.  I think the HTC/Verizon mash-up operating system is just so crappy it crashes and forces a reboot.  I’ve noticed that this happens when the network flips around a lot.  I’ve also noticed it booting for no apparent reason.

What’s also special is that apps just disappear off your phone following a reboot.  Once your phone restarts, you have to give it several moments of 4G time to restore whatever apps it randomly deleted.  Totally weird behavior.  It’s almost like using a Windows operating system.

4. I’ve Lost My Network and I Can’t Get Up

Several times with this Thunderbolt I’ve noticed that I’m stuck in 1G mode.  I try toggling the mobile network connection off/on to reset it, but it always comes back to the 1G network.  This occasionally happens when it gets stuckin 3G mode as well.  (Funny, I’ve never seen 2G…)

The only way I’ve found to fix this problem is to force a restart.  When the phone regains consciousness, it happily joins the 4G network.

5. Sucks like a Starving Vampire

Granted, the Gingerbread update is supposed to fix a lot of the issues with the HTC Thunderbolt’s ability to drain your battery faster than a starving vampire in a blood bank.  I even upgraded, spending about $50, for a uber-battery, doubling the phone’s weight and thickness.  It’s worth it, though, having a battery that can last me on the train ride between San Jose and San Francisco.

There’s entire web pages devoted to tricks and tips to prolonging the battery life on this phone all of which basically involve crippling, or at least diminishing, all of the features that justified the purchase of your phone in the first place.

I’m really hoping Gingerbread offers better battery life as, since I don’t live in a winter-zone anymore, it’s a shame to waste the hand-warming features of a rapidly depleting battery.

 

So…I un-rooted my phone so that I could get the Gingerbread update, replacing Froyo on this phone.  I have no idea why it takes Verizon so long to roll-out these updates.  Perhaps their visual basic programmers are having a hard time with all the Android unixey stuff.  Who knows?  I mean, you have to make sure that the user can’t delete the fucking golf demo, right?

When Gingerbread was finally available for the Thunderbolt, the update lasted all of a day, if that, before Verizon yanked the update from the download stream.  It was as if they were like: QA testing?  We’ve heard of that…  The update was so bug-ridden that it was disabling or severely-impairing phone functionality.

Now, as of yesterday, they’re starting to push the Gingerbread update back out to the users.  At a time when Google is announcing the Ice Cream Sandwich update (the successor to Gingerbread), Verizon, after one false-start, is now only 1 release behind on the operating system.

Tell me — why am I paying premium rates for a phone Verizon and HTC can’t keep current?

So, as soon as I come into a little cash, I think I will call Verizon customer services (snicker) and complain to them about this phone and their inability to provide a stable (or current) operating system platform.  I’d like to negotiate them into a new Motorola Android phone…Verizon seems ti play better with Motorola — timely updates, better hardware, non thermo-radioactive battery, etc.

I want to stay in the Google universe because everything works there.  The iPhone is looking sexy — but it’s still not 4G…not yet…

mongodb.findOne() — calling with PHP variables (not literals)

Category : Technical
No Gravatar

So I’ve been doing a lot of work, for work, in MongoDB lately and I’ve learned an awful lot.  Or, depending on your point of view, a lot that’s just awful.

See, there’s not what you could even charitably call a lot of MongoDB documentation to begin with.   If you filter what is available on, oh, say, PHP implementation, well the results just dwindle to something roughly the same size as a tax-collector’s heart.

Here’s the scenario — I’ve been working on adding a mongo abstraction class on top of my base-data abstraction class — whereas said classes are extended by the table-level class instantiation.  This allows me to keep all of my query logic in the middle tier of the class design, generic and administrative functions in the base class, and table-specific stuff in the table class.  So far, so good, right?

Well, I get the mongo constructor running and, like it’s mySQL counterpart, I have an rule in every table constructor that states “if I pass a indexed field and it’s value to the constructor, then instantiate the class pre-populated with that record.”

And that’s where things start to head south.

In my constructor logic, I’m only allowing single-value key->value pairs as constructor parameters with the design intention of getting a record from the db using the pkey of the table/collection.  In other words, you get one column and one column value.  So, if you’re going to instantiate a new user object, you’d probably want to pass-in the primary-key field of a user and that field’s value:

$objUser = new UserProfile(‘email’, ‘mshallop@gmail.com’);   // instantiate a new user object with this email address

Still pretty easy.  I bang out the mySQL equivalent in nothing flat.  I hit a huge pothole when I get to the mongo side.

The method is defined as a protected abstract method in the base class – so this method has to appear in both child classes as defined in the parent:

protected abstract function loadClassById($_key, $_value);

So I have my methods defined in both the mySQL and mongoDB middle layer.  My strategy for the mongo fetch-and-return is pretty simple — once the class has been instantiated, do the following:

  1. make sure the $_key value exists in the allowed field list
  2. make sure the $_value has a value
  3. query mongodb using .findOne()
  4. store the return key->value pairs in the member array
  5. return status

That’s pretty much it.  But I run into huge problems when I get to step 3 — use the mongoDB findOne command.

The findOne method takes an array input of the key->value pair.  From the mongo command line, you’d execute something like this:

> db.session_ses.findOne({'idpro_ses' : 1})
{
 "_id" : ObjectId("4ea1af93ddc69802376b56d1"),
 "id_ses" : 1,
 "idpro_ses" : 1
}

( Just to show you that the data exists in the mongo collection…)

But, the PHP-ized version of the method is a wee bit different:

$this->collection->findOne(array(‘idpro_ses’ => 1));

All of the examples that I’ve been able to locate show using the method by invoking it using literals.  My problem is that I have the two input parameters sent to the method ($_key and $_value) and I’ve got to find a way to get the PHP version of the method call to work using variables instead of constants.  This is what didn’t work:

$this->collection->findOne(array($_key => $_value));

$this->collection->findOne(array(“‘” . $_key . “‘” => $_value));

 

$this->collection->findOne(array(“{$_key}” => $_value));

$aryData = array();
$aryData[$_key] = $_value;
$this->collection->findOne($aryData);
or
$this->collection->findOne(var_dump($aryData)); 

I thought this worked but I was wrong:

$this->collection->findOne(array(array_keys($aryData) => array_values($aryData)));

This format returned a mongo record — the problem was that it returned the first mongo record independently of any key-search criteria.

What finally worked for me was this:

            $qs = array(); // QueryStructure
            switch($this->fieldTypes[$_k]) {
                case 'int' :
                    $_v = intval($_v);
                    break;
                case 'str' :
                    $_v = strval($_v);
                    break;
                case 'float' :
                    $_v = floatval($_v);
                    break;
            }
            $qs[$_k] = $_v;
            $aryData = $this->collection->findOne($qs);

[Update]

I encountered a similar problem when trying to update records in a mongo collection — while I could update the record from the mongo command line, I did not experience the same success in trying to execute the command from within my PHP program…

$foo = $collection->find(array(‘id_geo’ => $row['id_geo']));

Consistently failed.  No exceptions were caught, and mongo’s findLastError() reported no errors in the transaction.

After several iterations of debugging and attempting various work-arounds, I stumbled upon the solution as being one of casting.  While the variable was being evaluated in the PHP array as type int, somehow this wasn’t being interpreted that way by Mongo.  Casting the variable to an integer:

$foo = $collection->find(array(‘id_geo’ => intval($row['id_geo']))); 

 generated a successful query for both the find() and my update() functions.

As I gain experience with Mongo, I expect to discover more of these little mannerisms…

Page optimized by WP Minify WordPress Plugin

Our weather forecast is from Wunderground for WordPress