/**
  * Get the SQL of a insert statement
  * @param zibo\library\database\manipulation\statement\manipulation\InsertStatement $statement
  * @return string SQL of the insert statement
  * @throws zibo\library\database\exception\DatabaseException when no table was added to the statement
  * @throws zibo\library\database\exception\DatabaseException when no values where added to the statement
  */
 protected function parseInsertStatement(InsertStatement $statement)
 {
     $tables = $statement->getTables();
     if (empty($tables)) {
         throw new DatabaseException('No tables added to the insert statement');
     }
     $table = array_shift($tables);
     $values = $statement->getValues();
     if (empty($values)) {
         throw new DatabaseException('No values added to the insert statement');
     }
     $sqlFields = '';
     $sqlValues = '';
     foreach ($values as $valueExpression) {
         $field = $valueExpression->getField();
         $value = $valueExpression->getValue();
         $value = $this->parseExpression($value);
         $sqlFields .= ($sqlFields == '' ? '' : ', ') . $this->connection->quoteIdentifier($field->getName());
         $sqlValues .= ($sqlValues == '' ? '' : ', ') . $value;
     }
     $sql = 'INSERT INTO ' . $this->connection->quoteIdentifier($table->getName());
     $sql .= ' (' . $sqlFields . ') VALUES (' . $sqlValues . ')';
     return $sql;
 }
 public function testInsertStatement()
 {
     $statement = new InsertStatement();
     $statement->addTable(new TableExpression('table'));
     $statement->addValue(new FieldExpression('field1'), new ScalarExpression('test'));
     $statement->addValue(new FieldExpression('field2'), new ScalarExpression(2));
     $statement->addValue(new FieldExpression('field3'), new ScalarExpression(false));
     $sql = $this->parser->parseStatement($statement);
     $this->assertNotNull($sql);
     $this->assertEquals('INSERT INTO `table` (`field1`, `field2`, `field3`) VALUES (\'test\', 2, 0)', $sql);
 }
 /**
  * Saves a has many value to the model of the field. This is a many to many field.
  * @param mixed $data Value of the has many field
  * @param string $fieldName Name of the has many field
  * @param integer $id Primary key of the data which is being saved
  * @param boolean $isNew Flag to see whether this is an insert or an update
  * @return null
  */
 private function saveHasManyAndBelongsToMany($data, $fieldName, $id, $isNew)
 {
     if (!is_array($data)) {
         throw new ModelException('Provided value for ' . $fieldName . ' should be an array');
     }
     $foreignKeys = $this->meta->getRelationForeignKey($fieldName);
     $foreignKeyToSelf = null;
     if (!is_array($foreignKeys)) {
         $foreignKeyToSelf = $this->meta->getRelationForeignKeyToSelf($fieldName);
         $foreignKeys = array($foreignKeys, $foreignKeyToSelf);
     } else {
         $foreignKeys = array_values($foreignKeys);
     }
     if (!$isNew) {
         if ($foreignKeyToSelf) {
             // relation with other model
             $this->deleteOldHasManyAndBelongsToMany($id, $fieldName, $foreignKeyToSelf);
         } else {
             // relation with self
             foreach ($foreignKeys as $foreignKey) {
                 $this->deleteOldHasManyAndBelongsToMany($id, $fieldName, $foreignKey);
             }
         }
     }
     $model = $this->meta->getRelationModel($fieldName);
     $linkModel = $this->meta->getRelationLinkModel($fieldName);
     $linkTable = new TableExpression($linkModel->getName());
     $foreignKey1 = new FieldExpression($foreignKeys[0]->getName());
     $foreignKey2 = new FieldExpression($foreignKeys[1]->getName());
     foreach ($data as $recordId => $record) {
         if (!is_numeric($record)) {
             $model->save($record);
             $recordNewId = $record->id;
         } else {
             $recordNewId = $record;
         }
         $statement = new InsertStatement();
         $statement->addTable($linkTable);
         $statement->addValue($foreignKey1, $recordNewId);
         $statement->addValue($foreignKey2, $id);
         $this->executeStatement($statement);
         $linkModel->clearCache();
     }
 }