Sunday, February 14

Geek

Oodles Of Noodles

I have a working base storage class for Pita.  Unfortunately, most of my weekend was eaten up by my day job and other miscellanea, but it does work.

I'll post the full code later in the week once I have a derived class or two that does something more useful, in the meantime, here's the test code to give you an example of how it's used:
def oodle_test():
  # Create a base view
  pets = Oodle()
 
  # Create some pets
  log('Creating pets')
 
  # Create a dog, and save it
  pet = pets.new()
  pet.animal = 'dog'
  pet.sound = 'woof'
  pet.save()
  log('Dog saved, %s pets' % pets.count(),1)
 
  # Create a cat from a dict, and save it
  pet = pets.new({'animal': 'cat', 'sound': 'meow'})
  pet.save()
  log('Cat saved, %s pets' % pets.count(),1)
 
  # Append an aardvark
  pet = pets.append({'animal': 'aardvark', 'sound': 'snorf'})
  log('Aardvark appended, %s pets' % pets.count(),1)
 
  # Append a hippopotamus too
  pet = pets.append(animal = 'hippopotamus', sound = 'hrooonk')
  log('Hippopotamus appended, %s pets' % pets.count(),1)
 
  # What pets do I have?
  log('Selecting all pets')
  for pet in pets.select():
    log('My %s says %s' % (pet.animal, pet.sound),1)
   
  # Select and find on fields
  log('Selecting specific pets')
  # What does my dog say?
  for pet in pets.select(animal = 'dog'):
    log('Selected my %s; it says %s' % (pet.animal, pet.sound),1)
   
  # Can I find my cat?
  pet = pets.find(animal = 'cat')
  log('Found my %s; it says %s' % (pet.animal, pet.sound),1)
   
  return pets.count() == 4
The base view class, which has no indexes, no persistence, and no support for sorting, is called an Oodle.

The results of the test?
Creating pets
  Dog saved, 1 pets
  Cat saved, 2 pets
  Aardvark appended, 3 pets
  Hippopotamus appended, 4 pets
Selecting all pets
  My dog says woof
  My cat says meow
  My aardvark says snorf
  My hippopotamus says hrooonk
Selecting specific pets
  Selected my dog; it says woof
  Found my cat; it says meow
Oodle OK
Update: We've hit version 0.02 wih a successful hash-table implementation.  Next up is persistence...  And deletes.

Update: 0.03!  I deleted my pet hippopotamus!

Update: 0.04!  The idiom for pet in pets now works.  You can't slice it or select within it yet.

Posted by: Pixy Misa at 11:34 PM | Comments (8) | Add Comment | Trackbacks (Suck)
Post contains 356 words, total size 3 kb.

1 So that was what the "noodle incident" was about!

Posted by: Steven Den Beste at Monday, February 15 2010 01:06 AM (+rSRq)

2 I'm guessing for the delete it would be something along the lines of...

if pet.select() = rabid
delete

wink
 


Posted by: Teresa at Monday, February 15 2010 04:00 AM (ZCuP9)

3 In theory, something like pets.select(status = 'rabid').delete() should work right now.  I'll add a test to the module to make sure.

Don't want rabid hippopotamuses cluttering up the place!

Posted by: Pixy Misa at Monday, February 15 2010 08:39 AM (PiXy!)

4 Okay, now you can do pets(status = 'rabid').delete() or even pets.delete(status = 'rabid').

Also, you can't call pets.delete() when you meant pet.delete - it would instantly wipe the entire view, so I made that an error.

Posted by: Pixy Misa at Monday, February 15 2010 08:54 AM (PiXy!)

5 If you call pets().delete(), though, you get what's coming to you!

Posted by: Pixy Misa at Monday, February 15 2010 08:55 AM (PiXy!)

6 I hope you wouldn't mind if i add some criticism to your interaction design. So, why do you need that .new() ? I prefer a bit more organized approach: cat = Oodles(...) or class Pet(Oodles): pass cat = Pet(...) so, why that Rubish .new() ? And I didn't get, why you need .new() and .append(); Also nobody will remember if they need to use .find or .select. Django uses .filter() and .get() names for purpose.

Posted by: Yuri Baburov at Wednesday, February 17 2010 06:16 AM (rBboi)

7 Yuri - thanks, I'm definitely open to suggestions on the method calls.  This was the result of one evening's work, and I'm sure I'll reorganise things as the codebase builds up.  (Which is starting to happen.)

So:

The structure of the database is not fixed at compile time.  You can create new views on the fly - and this is the normal way to do things.  It's not an OODBMS, it's a document database.  That's why I'm not subclassing to build the individual views.

Now, as to the .new() - you have a good point here with regards to expected Pythonicity.  But what I'm doing is saying pets = Oodle() to create a collection of pets, and pet = pets.new() to create an item in that collection, not an instance of pets.

I'm using the idiom for pet in pets(species = 'wombat'): ... to iterate over the collection, which would conflict with pet = pets() to create a new item.

.append() is a create-and-commit operation - or .new() and .save() in this case.

I can use .filter() and .get() in place of .select() and .find().  (In fact, select is now redundant.)  I haven't worked out the syntax for range matches and full-text searches / regex scans yet, so there's room for some changes there.  The difference between the two is that .select() returns a generator, where .find() returns a record.

Posted by: Pixy Misa at Wednesday, February 17 2010 10:30 AM (PiXy!)

8 Just thinking it over, I can use for pet in pets(species = 'wombat') for iterating, and pet = pets['rover'] to look up a unique item - assuming the view is a hash table or has a simple primary key.  If not, pet = pets[{'name': 'rover'}] would work, but then you may as well type pet = pets.find(name = 'rover') (or pet = pets.get(name = 'rover'), perhaps).

Posted by: Pixy Misa at Wednesday, February 17 2010 01:24 PM (PiXy!)

Hide Comments | Add Comment

Comments are disabled. Post is locked.
51kb generated in CPU 0.0125, elapsed 0.1019 seconds.
56 queries taking 0.0935 seconds, 345 records returned.
Powered by Minx 1.1.6c-pink.