/**
  * Parse SQL with types from sql in the form of "INSERT INTO testPreparedStatement(id, name) VALUES(?int, ?varchar)"
  * @param string $sql
  * @param array $lobs names of clob and blob fields from query
  * @return boolean
  */
 protected function parseSQL($sql, array $lobs = array())
 {
     if (empty($this->DBM)) {
         $this->log->error("Prepare failed: Database object missing");
         return false;
     }
     if (empty($sql)) {
         $this->log->error("Prepare failed: empty SQL statement");
         return false;
     }
     $this->sqlText = $sql;
     $this->log->info("Parse Query: {$sql}");
     // Build fieldDefs array and replace ?SugarDataType placeholders with a single ?placeholder
     $cleanedSql = "";
     $nextParam = strpos($sql, "?");
     if ($nextParam == 0) {
         $cleanedSql = $sql;
     } else {
         // parse the sql string looking for params
         $row = 0;
         while ($nextParam > 0) {
             $cleanedSql .= substr($sql, 0, $nextParam + 1);
             // we want the ?
             $sql = substr($sql, $nextParam + 1);
             // strip leading chars
             // scan for termination of SugarDataType
             $sugarDataType = "";
             for ($i = 0; $i < strlen($sql) and strpos(",) ", substr($sql, $i, 1)) === false; $i++) {
                 if (strpos(",) ", substr($sql, $i, 1)) == false) {
                     $sugarDataType .= substr($sql, $i, 1);
                 }
             }
             if ($sugarDataType === "") {
                 // no type, default to varchar
                 $sugarDataType = 'varchar';
             }
             // insert the fieldDef
             $this->fieldDefs[$row]['type'] = $sugarDataType;
             if ($this->DBM->isTextType($sugarDataType)) {
                 if (empty($lobs)) {
                     $this->log->fatal('Name of lob field is not specified: ' . $this->sqlText);
                     return false;
                 }
                 $this->lobFields[$row] = array_shift($lobs);
             }
             $sql = substr($sql, $i);
             // strip off the SugarDataType
             $nextParam = strpos($sql, "?");
             // look for another param
             $row++;
         }
         // add the remaining sql
         $cleanedSql .= $sql;
     }
     $this->parsedSQL = $cleanedSql;
     return true;
 }
 /**
  * This function adds records to FTS queue.
  *
  * @param $records array of records
  */
 protected function addRecordsToQueue($records)
 {
     $this->logger->info('addRecordsToQueue');
     $db = DBManagerFactory::getInstance('fts');
     $db->resetQueryCount();
     foreach ($records as $rec) {
         if (!is_array($rec) || empty($rec['bean_id']) || empty($rec['bean_module'])) {
             $this->logger->error('Error populating fts_queue. Empty bean_id or bean_module.');
             continue;
         }
         // support multiple values for 'processed'
         $rec['processed'] = empty($rec['processed']) ? 0 : $rec['processed'];
         $query = sprintf("SELECT id, processed FROM fts_queue WHERE bean_id = %s AND bean_module = %s", $db->quoted($rec['bean_id']), $db->quoted(BeanFactory::getBeanName($rec['bean_module'])));
         $res = $db->query($query, true, "Error get records from queue for fts");
         if ($item = $db->fetchRow($res)) {
             if ($item['processed'] != $rec['processed'] && $item['processed'] != 0) {
                 $query = sprintf("UPDATE fts_queue SET processed = %s, date_modified = current_timestamp WHERE id = %s", $db->quoted($rec['processed']), $db->quoted($item['id']));
                 $db->query($query, true, "Error update record in queue for fts");
             }
         } else {
             $beanName = BeanFactory::getBeanName($rec['bean_module']);
             if (empty($beanName)) {
                 $GLOBALS['log']->error("Full indexer: Failed to get bean name for module: {$rec['bean_module']}");
                 continue;
             }
             $query = sprintf("INSERT INTO fts_queue (id, bean_id, bean_module, processed, date_created)\n                        values (%s, %s, %s, %s, %s)", $db->quoted(create_guid()), $db->quoted($rec['bean_id']), $db->quoted($beanName), $db->quoted($rec['processed']), $db->now());
             $db->query($query, true, "Error populating index queue for fts");
         }
     }
     /*
      * The full indexer jobs should already be present when a full reindex
      * has been scheduled earler on. Those are presistent jobs and will
      * remain in the job queue to process new reocrds from the fts_queue.
      *
      * If a full indexer job is manually removed, scheduling again a full
      * reindex will trigger restoration of the full indexer jobs where needed.
      */
 }