fRecordSet Woes / Help Please!

fRecordSet Woes

I've been playing with flourish for many months now. I love it. Unfortunately, I never could figure out how to work with recordsets properly. Sometimes I could get them to work. Other times they wouldn't. In frustration, I gave up and just did everything with raw SQL and fResult.

I've decided to give it another go and am running into problems again. Could someone please explain to me what is going on here?

I have 2 examples. One works great, the other does not:

WORKING EXAMPLE : Table Definition:

CREATE  TABLE IF NOT EXISTS `pegs`.`peg_formats` (
  `peg_formats_id` TINYINT UNSIGNED NOT NULL AUTO_INCREMENT ,
  `format` VARCHAR(3) NOT NULL ,
  `created` TIMESTAMP NOT NULL ,
  PRIMARY KEY (`peg_formats_id`) )
ENGINE = InnoDB
<?php
 
/**
 * Queries for the peg_formats table
 */
class PegFormat extends fActiveRecord
{
    /**
     * Used to indicate if a failure or exception is the cause of a false return 
     * @var BOOL
     */
    static $status = TRUE;
    
    /**
     * Used to report back errors or messages
     * @var String
     */
    static $msg = '';
    
    /**
     * The flourish resultSet or recordSet object.
     * 
     * Can be used for getting the final SQL in event of an error.
     * @var Object
     */
    static $result = '';
 
    /**
     * Required by flourish
     * @return 
     */
    protected function configure()
    {
    }
    
    /**
     * Collect all records from the peg_formats table.
     * 
     * @return Object|BOOL    // fResult object or false if no records 
     */
    public static function fetchPegFormats()
    {
        // Reset $msg and status
        self::$status = TRUE;
        self::$msg = '';
        self::$result = '';
        
        try
        {
            $result = fRecordSet::build(__CLASS__);
            $result->tossIfEmpty();
            
            return self::$result;
            
        } catch ( fEmptySetException $e ) { return FALSE; } catch ( fException $e ) { self::$status = FALSE; self::$msg = $e; return FALSE; }
    }
 
}  // End of class PegFormat
?>

FAILING EXAMPLE : Table definition:

CREATE  TABLE IF NOT EXISTS `pegs`.`peg_infos` (
  `peg_number` SMALLINT UNSIGNED NOT NULL ,
  `peg_name` VARCHAR(15) NOT NULL ,
  `created` TIMESTAMP NOT NULL ,
  PRIMARY KEY (`peg_number`) ,
  UNIQUE INDEX `peg_name` (`peg_name` ASC) )
ENGINE = InnoDB
<?php
 
/**
 * Queries for the peg_infos table
 */
class PegInfo extends fActiveRecord
{
    /**
     * Used to indicate if a failure or exception is the cause of a false return 
     * @var BOOL
     */
    static $status = TRUE;
    
    /**
     * Used to report back errors or messages
     * @var String
     */
    static $msg = '';
    
    /**
     * The flourish resultSet or recordSet object.
     * 
     * Can be used for getting the final SQL in event of an error.
     * @var Object
     */
    static $result = '';
    
    /**
     * Required by flourish
     * @return 
     */
    protected function configure()
    {
        fORM::addCustomClassTableMapping($this, 'peg_infos');        
    }
    
    /**
     * Collect all records from the peg_infos table.
     * 
     * @return Object|BOOL    // fResult object or false if no records 
     */
    public static function fetchPegInfos()
    {
        // Reset $msg and status
        self::$status = TRUE;
        self::$msg = '';
        self::$result = '';
        
        try
        {
            
            $result = fRecordSet::build(__CLASS__);
            $result->tossIfEmpty();
            return self::result;
            
        } catch ( fEmptySetException $e ) { return FALSE; } catch ( fException $e ) { self::$status = FALSE; self::$msg = $e; return FALSE; }
    }
 
}  // End of class PegInfo
?>

As you can see, they are virtually identical. Unfortunately, I get the following exception for the PegInfo? class:

        exception 'fProgrammerException' with message 'The table specified, peg_info, does not exist in the database' in /Users/JBN/Dropbox/Work-PC/app/pegs_db/flourish/fSchema.php:1977
Stack trace:
#0 /Users/JBN/Dropbox/Work-PC/app/pegs_db/flourish/fActiveRecord.php(816): fSchema->getKeys('peg_info', 'primary')
#1 /Users/JBN/Dropbox/Work-PC/app/pegs_db/flourish/fActiveRecord.php(351): fActiveRecord->__construct()
#2 /Users/JBN/Dropbox/Work-PC/app/pegs_db/flourish/fRecordSet.php(161): fActiveRecord::forceConfigure('PegInfo')
#3 /Users/JBN/Dropbox/Work-PC/app/pegs_db/models/PegInfo.php(52): fRecordSet::build('PegInfo')
#4 /Users/JBN/Dropbox/Work-PC/app/pegs_db/controllers/FileProcessor_Controller.php(65): PegInfo::fetchPegInfos()
#5 /Users/JBN/Dropbox/Work-PC/app/pegs_db/scripts/process_sentinel_files.php(20): FileProcessor_Controller->__construct()

Why does flourish think the table name should be 'peg_info'? Notice I even added "fORMaddCustomClassTableMapping($this, 'peg_infos');" to the configure method to force the use of peg_infos ?

Any suggestions?

  • Message #381

    It appears your timing was just right to run across a bug in fActiveRecord that I introduced last week. If you get r694 or newer, you should be able to get PegInfo to work properly.

    • Message #382

      Updating to r694 did the trick. However, I don't understand why I needed the addCustomClassTableMapping in the first place. Why would fActiveRecord think the table should be named peg_info vs. peg_infos?

      • Message #383

        Two reasons, however it was an unrelated bug that caused your issues.

        First, a common pattern in database design is to have a table name be the plural of what is being stored in it. So a table containing login records would be called logins. Flourish uses this pattern for its default mapping.

        Second, the word info is an abbreviation of information. Information is a word that is the same in both the singular and plural form. Thus, fActiveRecord was looking for the plural underscore notation version of PegInfo?, which just so happens to be peg_info. In your case, you pluralized info with an s, which the code wasn't expecting.

        fGrammar is pretty smart about getting the proper form of common irregularly pluralized nouns. For instance it knows the plural of person is people, etc.

        • Message #384

          Thanks for the clarification. I'm used to the need for pluralized table names. Unfortunately, I've become so used to it that I put an "s" et the end of every table name now. I didn't realize fGrammar was actually capable of determining proper pluralization.