How To Use EditGrid to Create a Database With A Slick User Interface With Zero Lines of Code
February 27th, 2008Morphing Grid by Dan Allison.
Ever find yourself with a data collection, and you can see the steps in your head, create a form, create a table? It’s a dry task that gets dryer by the minute once you find yourself once again creating that paged results table for the contact us or event registration form you’ve created a thousand times before.
I can’t tell you how much slicker it is to send that data directly to an EditGrid workbook. It is a quick and easy database that is intuitive for your users. Instead of a paged html table, their information is available as rich full-featured spreadsheet.
comments
A Programmer’s Notebook on the EditGrid API
February 27th, 2008My Tchotchke Boxes by 1213 1982.
I created a series of online spreadsheets of every building, construction and demolition permit issuesd in Orleans Parish since January 2005. These spreadsheets are available at Think New Orleans.
The EditGrid API can automate the creation of reports and act as an easy use and share database for light data collection applications. I’ll write about my experience with EditGrid and why you should consider EditGrid at the back end for your next data collection task.
This is my programmer notebook on my getting to know you time with EditGrid.
I wrote my program in Java. Here are the three gotchas that I encountered.
Disabled Form Elements Are Not Submitted
January 6th, 2008Not in Firefox, at least.
Sheaf
December 15th, 2007Sheaf Toss by Ian Langworth.
Last Saturday morning, on my way to Fair Grinds for my morning coffee, something occurred to me about persistent object storage. I’m less certain as to why. I’ve not thought about that component of my application development in a long time. I implemented persistent storage using the basics of the malloc algorithm in a project that I called Bento.
Pages of Blocks with Identifiers
When I got to Fair Grinds I began to exchange instant messages with Brian Kerr or Ann Arbor, Michigan. I described the idea as follows.
A fixed page length, 8k or 16k. The address is a file position plus a short. It is a big address, I know. The blocks are stored in a page with a number to identify the blocks followed by the object length followed by the block data. To find a block, to the file position, load the page into memory, skip through the blocks until you find the one with the matching block number.
Within a page the block is sought so that within a page blocks can be relocated within the page. If a block is deleted, the contents following the block are shifted up. The moved blocks can still be found because we are skipping through the page form an offset.
Then Brian started asking questions and sorting out details. It was good to have someone think about the problem.
If you have a block larger than a single page, you break it up among pages. You use however many empty pages necessary to hold the block and put the remainder in a page that contains many blocks.
The file format supports journaling, so there is a concept of isolation. Isolation is modeled with a Mutator object. Changes to the file are called a mutation, rather than a transaction, since transaction implies a lot more hocus-pocus.
While the file format can handle concurrent requests, it cannot handle concurrent requests on the same block. It is up to the application developer to ensure that no two threads mutate the same block at the same time. It is up to the application developer to ensure that no thread reads a mutating block. The only manipulation that is permitted concurrently is read. Block allocations are going to be visible only to the thread that allocated them. Writes and frees are going to require synchronization on the part of the application.
In memory, a sorted map of lists of blocks with free space remaining is kept sorted on the amount remaining rounded down to an alignment. When a block is allocated it is rounded up to the next alignment and we search for the block with the smallest amount remaining that can fit the block. That block is used.
Separately, there is a list of pages that have been entirely emptied through deallocations.
The file format uses ByteBuffer objects kept in memory as buffers that represent the contents on disk. The ByteBuffer objects indicate what the disk will look like when the contents of the page are journaled. They can be out of sync with the file, but that is OK. This discrepancy between our in memory representation of the file and the on disk representation of the file allow us to implement journaling.
Commits to this file format are journaled. There are two journals available, an external file journal and an internal journal that uses pages in the file. For the internal journals the file format keeps a block of pointers in the header of the file. The default number of pointers is 64. To create a journal, one of the pointers is set to the address of the first page in a linked list of pages. This is set in the ByteBuffer that is in memory, however and not on disk. The address of the start of the linked list of journal pages is now written out until the journal commits. It is written out last and the file channel is forced to flush. Thus, on disk the pointers will only ever point to a complete journal.
In addition to a linked list of journal pages of journal actions, like allocate, write and free, the journal needs to allocate temporary blocks where the mutation can write changes without disturbing the actual block in memory or on disk. The temporary block contains the applications intent. It is copied over to the actual block during commit.
Delete Makes the File Grow
I set out to implement the file format. I’d hoped to have tests running on Monday. I begged off engagements. I sat before my computer and worked through each next logical task. I was not finished on Monday, so I forced myself to stop and resume my civic pursuits, while fiddling with the code and the concepts in my free time.
By Friday, the idea of the block identifier has run it’s course, before the code was complete.
An external journal meant that this file format would create a nice and compact file format. An internal journal would fill the file with empty journal pages. What really tripped me up was when I realized deletion could not be implemented as simply shifting the blocks following a deleted block up if I wanted the deletion to be journaled. The destination and the source of the copy were on the same page. If the page were to be corrupted their would be no way to recreate it. I would have to allocate copies of blocks following the deleted block in the journal. They would be safely on disk as part of the journal commit. The delete would then copy the blocks over from the journal.
This meant that a delete would actually cause the file to grow and grow large. If the first block on a page is deleted, a temporary block has to be allocated for all the other pages in the block. I couldn’t imagine myself very happy with a larger file.
Can the file ever shrink? Sure. If the pages at the end of the file empty, then we can truncate the file. We can always be on the lookout for empty pages at the end of a mutation and rewind the file.
But then, imagine a case where an application deletes a very large collection of objects. These deletions consume all the free pages for the journal. Then the deletions begin to create new journal pages at the end of the file. If another thread allocates a new object, the other thread couldn’t make use of all the free space created in isolation so it would have to allocate a block from a new page at the end of the file. When the thread with the deletions completes, it will free all of the journal pages, but the file cannot be rewound because there is a user page following all the freed journal pages.
The file would have a huge swath of empty pages just before the last page in the file. They would be reused eventually, but how counter-intuitive to delete objects and have the database grow in size on disk. That would be so hard to explain to people. It feels wrong.
I started to think about indirection, and a name for a new project.
Not a Blog Post, Not a Wiki Page, I Want An Ongoing Conversation
December 4th, 2007Lance Hill sent me a link to another article by Adam Nossiter in the New York Times. Nossiter is off drinking at the trough of Uptown’s conventional wisdom in his article Whites Take a Majority on New Orleans’s Council.
There is a post at Think New Orleans called Is Adam Nossiter a Tool? That question stands. I don’t want to write a new article about the matter, but rather have people continue to discuss the issue under the existing article. What I really want is a website that will allow me to feature this article once again, or rather bring this subject up in the context of the conversations that took place before. It is very important to preserve both the existing discussion and the timeline of events.
Which is something that is common to most of my civic writing. I do want to encourage participation in the conversation, so I want to resurrect the existing conversation, with the exisiting participants. Most people subscribe to email notifications of comments of a particular post. To notify them that Adam Nossiter is banging on about race and quoting Greg Rigamer, I need to continue the discussion under the previous post.
Although, I’m pleased that WordPress is now performing acceptably, both blogs and Wikis fail to make my efforts in New Orleans easier.
PLEAC-Groovy
December 3rd, 2007I came across this resource months ago. I forgot about it until I recently discovered an email that I sent to the author expressing my awe. It is a translation of the Perl Cookbook into Groovy.
ArborWiki Style and Forms
November 27th, 2007In an IM exchange with Matt Hampel of ArborWiki, we discussed how I’m using the ArborWiki theme to create a new, database driven implementation of the List of New Orleans Bloggers. I asked Matt about forms and he pointed me toward work that he’d done at Ann Arbor’s Community High School, specifically the form guidelines for the school’s website. Moreover, he sent a link to a blog called Functioning Form where I found a post called Web Form Design Best Practices which has a presentation in PDF that is a great start in understanding form design.
I Want To Put My Asides Aside
August 6th, 2007That is going to be my programming project tomorrow. Putting my asides in the sidebar of the index page. I’d like to have categories breakout out with a main content channel and asides. I want my asides to be permitted to be longer than one paragraph as well. Asides are also called life streams. For added effect it could be animated on mouse over, or it could scroll itself.
| « Previous Entries |




