Speedups, bugfixes, and fleshing out current AbstractDataFrame API

@tshort The third commit is the one of interest, where I shuffled around code between DataFrame and AbstractDataFrame, and fleshed out a transient interface
I like the more explicit error message here -- the thing I'm torn on is that this tack leads to slow or broken methods left in when someone adds a type (it feels like a large part of my involvement with the package has been rooting out issues like this hidden throughout the codebase). 

Perhaps leaving the DataFrame method that's in the code and defining the version you wrote above for AbstractDataFrame would be a good compromise. Alternately, defining `save` for that new abstract type -- seems like it needs a tentative name, but best I've thought of is `abstract DirectDataFrame <: AbstractDataFrame`.