/** * Query the data source. * <p>This class makes no assumption about the content of the query * object, but the behavior of the resulting Cursor object should be * consistent between data source implementations. * @param mixed $query Some sort of query that will be understood by * the implemented data source. * @return Cursor The result of the query, FALSE if the query failed. */ function &query($query) { if ($this->isConnected) { if (IsLogEnabled('DEBUG')) { LogDebug("querying for: \n" . print_r($query, TRUE), $this); } $rv = FALSE; return $rv; } else { if (IsLogEnabled('ERROR')) { LogError("Cannot run query: \n" . print_r($query, TRUE) . "\ndata source is not connected: " . print_r($this, TRUE)); } LogFatal("Error running query."); } }
/** * Log a fatal message. * @param string $message The message. */ function fatal($message) { LogFatal($message, $this); }
/** * Close the connection to the MySQL data source. * <p>Not only does this happen automatically on shutdown, but MySQL * also closes open connetions on shutdown. Only one will matter since * the other will notice that the connection is closed and not attempt * to close it again. However, it is entirely unnecessary to call * shutodwn() from an application that uses a MySQL data source unless * you want to explicitly shut down the data source. * @return TRUE if successful, FALSE otherwise. */ function shutdown() { if (!parent::shutdown()) { if (!mysql_close($this->myLink)) { LogFatal("Unable to shut down MySQL connection: " . mysql_error()); return FALSE; } } return TRUE; }
/** * Query the user input. Recognizes this minimal SQL statement form: * * select key1,key2,key3,etc * from assoc_array * where id_key = value * * TODO: Currently does not recognize update, insert, or delete queries * though a short leap of logic could imagine that update and insert * queries might thunk HTML output for displaying/editing a persistent * object. I'm not sure that logic can leap so far as to delete a an * object from the user. * * @param string $query An SQL select statment of the format noted * above. * @return Cursor The result of the query, FALSE otherwise (though this * is unlikely to occur because of the fatal error event when a query * fails). */ function &query($query) { if (!($rv =& parent::query($query))) { $parts = array(); if (eregi("select(.*)from(.*)where(.*)", $query, $parts)) { $fields = array(); $table = trim($parts[2]); $where = trim($parts[3]); $wparts = array(); if (eregi("(.*)=(.*)", $where, $wparts)) { #LogDebug( $wparts ); $idfield = ExtractFieldAlias($table, $wparts[1]); $idmatch = trim($wparts[2]); $tmp = array(); if (ereg("^\\'(.*)\\'\$", $idmatch, $tmp)) { $idmatch = $tmp[1]; } } elseif (eregi("(.*) is null", $where, $wparts)) { $idfield = ExtractFieldAlias($table, $wparts[1]); $idmatch = NULL; } else { LogError("Invalid user input where clause: {$query}"); LogFatal("Invalid user input where clause"); } $gotid = FALSE; foreach (split(',', $parts[1]) as $field) { $alias = ExtractFieldAlias($table, $field); if ($idfield == $alias) { $gotid = TRUE; } $fields[] = $alias; } } else { LogError("Invalid user input query: {$query}"); LogFatal("Invalid user input query"); } $rv = array(); if (array_key_exists($table, $_REQUEST) && is_array($tin = $_REQUEST[$table])) { #LogDebug( "--$idfield--" ); #LogDebug( $tin ); if (array_key_exists($idfield, $tin)) { if ($rec = ExtractRecordFromRequest($table, $idfield, $idmatch, $fields, $tin)) { $rv[] = $rec; } } else { foreach ($tin as $trow) { if ($rec = ExtractRecordFromRequest($table, $idfield, $idmatch, $fields, $trow)) { $rv[] = $rec; } } } } else { if ($rec = ExtractRecordFromRequest($table, $idfield, $idmatch, $fields, $_REQUEST)) { $rv[] = $rec; } } } $r = new ArrayCursor(&$rv, &$this); #LogDebug($r); return $r; }
/** * Get a configuration object. * @param mixed $initialConfig The external configuration object or array to * use for setting up initial values. May be an existing Configuration * object, in which case no other is constructed. */ function &GetConfigurationRef(&$initialConfig) { global $GETCONFIGURATION_HELPER; if (is_a($initialConfig, "AtsumiObject")) { $chelp = $initialConfig; } else { $GETCONFIGURATION_HELPER->setref($initialConfig); $chelp = $GETCONFIGURATION_HELPER; } if ($chelp->has('configuration-class')) { $configclass = $chelp->get('configuration-class'); } else { $configclass = 'Configuration'; } if (!class_exists($configclass)) { if (IsLogEnabled('ERROR')) { LogError("Configuration class {$configclass} is not defined:\n" . print_r($initialConfig, TRUE)); } LogFatal("Invalid configuration"); $rv = FALSE; return $rv; } else { if (is_a($initialConfig, $configclass)) { $rv =& $initialConfig; } elseif (is_a($initialConfig, 'Configuration')) { $ic =& $initialConfig->get(); $rv = new $configclass($ic); } else { $rv = new $configclass($initialConfig); } if (!is_a($rv, 'Configuration')) { if (IsLogEnabled('ERROR')) { LogError("{$configclass} is not a Configuration subclass:\n" . print_r($initialConfig, TRUE)); } LogFatal("Invalid configuration"); $rv = FALSE; } return $rv; } }
/** * Implementation of load and import varies only slight, so both * methods refer to this helper method. * @param bool $do_load TRUE for load, FALSE for import. * @param ChunsuObject $loadme The object to load. * @param DataSource $source The data source to load the object from. * @return bool TRUE is successful, FALSE otherwise. */ function loadOrImport($do_load, &$loadme, $source) { $pkfield =& $this->config->get('primary-key'); $pka =& $pkfield->get('alias'); $core =& $loadme->getCore(); if (is_array($core) || is_object($core)) { $dummy =& $loadme->getDummy(); $pkval = $dummy->get($pka); } else { $pkval = $core; } if (!is_null($pkval)) { $gen = new SQLGenerator($loadme->getCore()); $cursor = $source->query($gen->select($this->config)); if ($cursor->getNext()) { $rec =& $cursor->get(); if ($do_load) { $loadme->setref($rec); $loadme->is_new = FALSE; } else { $loadme->bulkSet($rec); } return TRUE; // TODO: keep reading and handle conflicts if >1 record } } if (!$loadme->config->get('create-on-save')) { LogError("Cannot load object: no records found.\n" . $loadme->trace()); LogFatal("Cannot load object: no records found. "); } return TRUE; }
/** * Get a configured storage method by name. * @param string $name The name of the storage method. */ function &GetStorageMethod($pobj, $name) { $pclass = get_class($pobj); $rv = FALSE; while ($pclass && strtolower($pclass) != 'atsumiobject' && !$rv) { $cf =& GetStorageMethods($pclass); if ($cf->has($name)) { $rv =& $cf->get($name); } $pclass = get_parent_class($pclass); } if (!$rv) { if (IsLogEnabled('ERROR')) { LogError("Non-existant storage method {$name} for\n" . print_r($pobj, TRUE)); } LogFatal("Non-existant storage method\n"); return FALSE; } else { return $cf->get($name); } }
/** * Create an AtsumiService object from a configuration. * @param mixed $config Either a Configuration object or something else * that may be used as the core representation of a Configurtion. * @param string $targetClass The class of service to be created. Target * class should be a subclass of AtsumiService, but a superclass of the * object returned by GetService. The class of the returned object is * specified in the configuration as 'service-class'. * @return AtsumiServie A service implementation. Returns FALSE if the * service could not be created and the fatal error handler doesn't kill * the script. */ function GetService(&$config, $targetClass) { if (!class_exists($targetClass)) { if (IsLogEnabled('ERROR')) { LogError("Target class {$targetClass} does not exist\n" . print_r($config, TRUE)); } LogFatal("Invalid service target class"); return FALSE; } $cf =& GetConfigurationRef($config); $serviceclass = $cf->get('service-class'); if (!$cf->has('service-class')) { if (IsLogEnabled('ERROR')) { LogError("Configuration does not specify a service class:\n" . "Please set the 'service-class' configuration option.\n" . "Target: {$targetClass}\n" . print_r($cf, TRUE)); } LogFatal("Invalid service configuration"); return FALSE; } elseif (!class_exists($serviceclass)) { if (IsLogEnabled('ERROR')) { LogError("Serivce class {$serviceclass} is not defined:\n" . "Target: {$targetClass}\n" . print_r($cf, TRUE)); } LogFatal("Invalid service configuration"); return FALSE; } else { $rv = new $serviceclass($cf); if (!is_a($rv, $targetClass)) { if (IsLogEnabled('ERROR')) { LogError("Configuration does not specify a service class:\n" . "Class {$serviceclass} is not a subclass of {$targetClass}.\n" . print_r($rv, TRUE) . print_r($cf, TRUE)); } LogFatal("Invalid service configuration"); return FALSE; } elseif (!is_a($rv, 'AtsumiService')) { if (IsLogEnabled('ERROR')) { LogError("Configuration does not specify a service class:\n" . "Class {$targetClass} is not a subclass of AtsumiService.\n" . print_r($rv, TRUE) . print_r($cf, TRUE)); } LogFatal("Invalid service configuration"); return FALSE; } else { return $rv; } } }