inline bool LoadDirectoriesTable(mysqlpp::Connection& databaseConnection,
     const std::string& schema) {
   if(TableExists(databaseConnection, schema, "directories")) {
     return true;
   }
   mysqlpp::Query query = databaseConnection.query();
   query << "CREATE TABLE directories ("
     "id INTEGER UNSIGNED PRIMARY KEY NOT NULL,"
     "name VARCHAR(100) BINARY NOT NULL)";
   return query.execute();
 }
 inline bool LoadChildrenTable(mysqlpp::Connection& databaseConnection,
     const std::string& schema) {
   if(TableExists(databaseConnection, schema, "children")) {
     return true;
   }
   mysqlpp::Query query = databaseConnection.query();
   query << "CREATE TABLE children ("
     "entry INTEGER NOT NULL,"
     "child INTEGER NOT NULL)";
   return query.execute();
 }
 inline bool LoadPermissionsTable(mysqlpp::Connection& databaseConnection,
     const std::string& schema) {
   if(TableExists(databaseConnection, schema, "permissions")) {
     return true;
   }
   mysqlpp::Query query = databaseConnection.query();
   query << "CREATE TABLE permissions ("
     "source INTEGER UNSIGNED NOT NULL,"
     "target INTEGER UNSIGNED NOT NULL,"
     "permission INTEGER UNSIGNED NOT NULL)";
   return query.execute();
 }
Пример #4
0
void FbMainDatabase::CreateFullText(bool force, FbThread * thread)
{
	if (IsReadOnly()) return;
	if ( !force && TableExists(wxT("fts_book_content")) ) return;
	FbSQLite3Transaction trans(this, WXSQLITE_TRANSACTION_IMMEDIATE);
	CreateTableFTS(wxT("book"), wxT("books"), wxT("title),LOW(description"), wxT(",dscr"));
	CreateTableFTS(wxT("auth"), wxT("authors"), wxT("full_name"));
	CreateTableFTS(wxT("seqn"), wxT("sequences"), wxT("value"));
	ExecuteUpdate(fbT("UPDATE books SET deleted=NULL WHERE deleted=0"));
	ExecuteUpdate(fbT("UPDATE authors SET letter=LTTR(full_name) WHERE id"));
	trans.Commit();
}
Пример #5
0
void FbMainDatabase::Open(const wxString& filename, const wxString& key, int flags)
{
	FbDatabase::Open(filename, key, flags);
	ExecuteUpdate(fbT("PRAGMA temp_store=2"));
	bool bExists = TableExists(GetMaster());
	InitFunctions();

	wxString message = bExists ? _("Open database") : _("Create database");
	FbLogMessage(message, filename);

	if (!bExists) CreateDatabase();
	UpgradeDatabase(DB_DATABASE_VERSION);
}
 inline bool LoadAccountsTable(mysqlpp::Connection& databaseConnection,
     const std::string& schema) {
   if(TableExists(databaseConnection, schema, "accounts")) {
     return true;
   }
   mysqlpp::Query query = databaseConnection.query();
   query << "CREATE TABLE accounts ("
     "id INTEGER UNSIGNED PRIMARY KEY NOT NULL,"
     "name VARCHAR(100) BINARY NOT NULL,"
     "password VARCHAR(100) BINARY NOT NULL,"
     "registration_time DATETIME NOT NULL,"
     "last_login_time DATETIME NOT NULL)";
   return query.execute();
 }
 inline bool LoadSettingsTable(mysqlpp::Connection& databaseConnection,
     const std::string& schema) {
   if(TableExists(databaseConnection, schema, "settings")) {
     return true;
   }
   mysqlpp::Query query = databaseConnection.query();
   query << "CREATE TABLE settings (next_entry_id INTEGER UNSIGNED NOT NULL)";
   if(!query.execute()) {
     return false;
   }
   query.reset();
   SqlInsert::settings settingsRow(0);
   query.insert(settingsRow);
   return query.execute();
 }
Пример #8
0
void CUpdateDBThread::DoUpdateDB()
{
	CString strSQL;

	//如果表不存在则创建

	// 2011/07/15-8201-gxx: 本地消费表,保存本地用户结账后的信息
	if (!TableExists(_T("LocalConsume")))
	{
		IBA_LOG0(_T("create table LocalConsume"));

		strSQL.Empty();

		strSQL = _T("CREATE TABLE `LocalConsume` (\
			`submitTime` datetime NOT NULL,\
			`netBarId` smallint(6) NOT NULL default '0',\
			`refNo` int(11) NOT NULL default '0',\
			`serialNo` int(11) default NULL,\
			`serialNum` varchar(20) default NULL,\
			`name` varchar(20) default NULL,\
			`idNumber` varchar(50) default NULL,\
			`memberId` int(11) default NULL,\
			`creditAmount` int(11) default NULL,\
			`consumeAmount` int(11) default NULL,\
			`returnAmount` int(11) default NULL,\
			`checkinTime` datetime default NULL,\
			`checkoutTime` datetime default NULL,");
		strSQL += _T("\
			`termId` varchar(8) default NULL,\
			`ClassId` tinyint(4) default '0',\
			`PayType` tinyint(4) default '0',\
			`PCClass` tinyint(4) default '0',\
			`timeConsume` int(11) default NULL,\
			`operator` varchar(30) default NULL,\
			`dataStatus` tinyint(4) default NULL,\
			`checkData` varchar(32) default NULL,\
			PRIMARY KEY  (`submitTime`,`netBarId`,`refNo`),\
			KEY `lc_serialnum` (`serialNum`),\
			KEY `lc_memberId` (`memberId`),\
			KEY `lc_termId` (`termId`),\
			KEY `lc_name` (`name`),\
			KEY `lc_idnumber` (`idNumber`)\
			) ENGINE=InnoDB DEFAULT CHARSET=gbk");

		ExecuteSQL(strSQL);
	}
Пример #9
0
void UsdxDatabase::Initialize()
{
	// Add table cUS_Statistics_Info
	// needed in the conversion from 1.01 to 1.1
	if (!TableExists(cUS_Statistics_Info))
	{
		sLog.Info("Database::Init", "Outdated song database found - missing table %s", cUS_Statistics_Info);

		FormattedExec("CREATE TABLE IF NOT EXISTS [%s] ([ResetTime] INTEGER);", cUS_Statistics_Info);

		// insert creation timestamp
		time_t now = time(nullptr);
		FormattedExec(
			"INSERT INTO [%s] ([ResetTime]) VALUES(" I64FMTD ");",
			cUS_Statistics_Info, now);
	}

	// convert data from 1.01 to 1.1
	// part #1 - prearrangement
	bool finalizeConversion = false;
	Sint32 version = GetUserVersion();
	if (version == 0 && TableExists(cUS_Scores))
	{
		// rename old tables - to be able to insert new table structures
		FormattedExec("ALTER TABLE %s RENAME TO us_scores_101;", cUS_Scores);
		FormattedExec("ALTER TABLE %s RENAME TO us_songs_101;", cUS_Songs);

		finalizeConversion = true; // means: conversion has to be done!
	}

	// Set version number after creation
	if (version == 0)
		SetUserVersion(cDBVersion);

	// SQLite does not handle VARCHAR(n) or INT(n) as expected.
	// Texts do not have a restricted length, no matter which type is used,
	// so use the native TEXT type. INT(n) is always INTEGER.
	// In addition, SQLiteTable3 will fail if other types than the native SQLite
	// types are used (especially FieldAsInteger). Also take care to write the
	// types in upper-case letters although SQLite does not care about this -
	// SQLiteTable3 is very sensitive in this regard.
	FormattedExec(
		"CREATE TABLE IF NOT EXISTS [%s] ("
		"[SongID] INTEGER NOT NULL, "
		"[Difficulty] INTEGER NOT NULL, "
		"[Player] TEXT NOT NULL, "
		"[Score] INTEGER NOT NULL, "
		"[Date] INTEGER NULL"
		");", cUS_Scores);

	FormattedExec(
		"CREATE TABLE IF NOT EXISTS [%s] ("
		"[ID] INTEGER PRIMARY KEY, "
		"[Artist] TEXT NOT NULL, "
		"[Title] TEXT NOT NULL, "
		"[TimesPlayed] INTEGER NOT NULL, "
		"[Rating] INTEGER NULL"
		");", cUS_Songs);

	// Add Date column to cUS_Scores
	if (!ColumnExists(cUS_Scores, "Date"))
	{
		sLog.Info("Database::Init", "Adding column [Date] to %s", cUS_Scores);
		FormattedExec("ALTER TABLE %s ADD COLUMN [Date] INTEGER NULL", cUS_Scores);
	}

	// Add Rating column to cUS_Songs
	// Just for users of nightly builds and developers!
	if (!ColumnExists(cUS_Songs, "Rating"))
	{
		sLog.Info("Database::Init", "Adding column [Rating] to %s", cUS_Songs);
		FormattedExec("ALTER TABLE %s ADD COLUMN [Rating] INTEGER NULL", cUS_Songs);
	}

	// convert data from previous versions
	// part #2 - accomplishment
	if (finalizeConversion)
	{
		// convert data from 1.01 to 1.1
		if (TableExists("us_scores_101"))
			ConvertFrom101To110();
	}
}
Пример #10
0
static int VerifyTablePromise(CfdbConn *cfdb, char *table_path, Rlist *columns, Attributes a, Promise *pp)
{
    char name[CF_MAXVARSIZE], type[CF_MAXVARSIZE], query[CF_MAXVARSIZE], table[CF_MAXVARSIZE], db[CF_MAXVARSIZE];
    int i, count, size, no_of_cols, *size_table, *done, identified, retval = true;
    char **name_table, **type_table;

    CfOut(cf_verbose, "", " -> Verifying promised table structure for \"%s\"", table_path);

    if (!ValidateSQLTableName(table_path, db, table))
    {
        CfOut(cf_error, "",
              " !! The structure of the promiser did not match that for an SQL table, i.e. \"database.table\"\n");
        return false;
    }
    else
    {
        CfOut(cf_verbose, "", " -> Assuming database \"%s\" with table \"%s\"", db, table);
    }

/* Verify the existence of the tables within the database */

    if (!TableExists(cfdb, table))
    {
        CfOut(cf_error, "", " !! The database did not contain the promised table \"%s\"\n", table_path);

        if ((a.database.operation) && (strcmp(a.database.operation, "create") == 0))
        {
            if ((!DONTDO) && ((a.transaction.action) != cfa_warn))
            {
                cfPS(cf_error, CF_CHG, "", pp, a, " -> Database.table %s doesn't seem to exist, creating\n",
                     table_path);
                return CreateTableColumns(cfdb, table, columns, a, pp);
            }
            else
            {
                CfOut(cf_error, "", " -> Database.table %s doesn't seem to exist, but only a warning was promised\n",
                      table_path);
            }
        }

        return false;
    }

/* Get a list of the columns in the table */

    QueryTableColumns(query, db, table);
    CfNewQueryDB(cfdb, query);

    if (cfdb->maxcolumns != 3)
    {
        cfPS(cf_error, CF_FAIL, "", pp, a, "Could not make sense of the columns");
        CfDeleteQuery(cfdb);
        return false;
    }

/* Assume that the Rlist has been validated and consists of a,b,c */

    count = 0;
    no_of_cols = RlistLen(columns);

    if (!NewSQLColumns(table, columns, &name_table, &type_table, &size_table, &done))
    {
        cfPS(cf_error, CF_FAIL, "", pp, a, "Could not make sense of the columns");
        return false;
    }

/* Obtain columns from the named table - if any */

    while (CfFetchRow(cfdb))
    {
        char *sizestr;

        name[0] = '\0';
        type[0] = '\0';
        size = CF_NOINT;

        strlcpy(name, CfFetchColumn(cfdb, 0), CF_MAXVARSIZE);
        strlcpy(type, CfFetchColumn(cfdb, 1), CF_MAXVARSIZE);
        ToLowerStrInplace(type);
        sizestr = CfFetchColumn(cfdb, 2);

        if (sizestr)
        {
            size = Str2Int(sizestr);
        }

        CfOut(cf_verbose, "", "    ... discovered column (%s,%s,%d)", name, type, size);

        if (sizestr && (size == CF_NOINT))
        {
            cfPS(cf_verbose, CF_NOP, "", pp, a,
                 " !! Integer size of SQL datatype could not be determined or was not specified - invalid promise.");
            DeleteSQLColumns(name_table, type_table, size_table, done, no_of_cols);
            CfDeleteQuery(cfdb);
            return false;
        }

        identified = false;

        for (i = 0; i < no_of_cols; i++)
        {
            if (done[i])
            {
                continue;
            }

            if (strcmp(name, name_table[i]) == 0)
            {
                CheckSQLDataType(type, type_table[i], pp);

                if (size != size_table[i])
                {
                    cfPS(cf_error, CF_FAIL, "", pp, a,
                         " !! Promised column \"%s\" in database.table \"%s\" has a non-matching array size (%d != %d)",
                         name, table_path, size, size_table[i]);
                }
                else
                {
                    CfOut(cf_verbose, "", " -> Promised column \"%s\" in database.table \"%s\" is as promised", name,
                          table_path);
                }

                count++;
                done[i] = true;
                identified = true;
                break;
            }
        }

        if (!identified)
        {
            cfPS(cf_error, CF_FAIL, "", pp, a,
                 "Column \"%s\" found in database.table \"%s\" is not part of its promise.", name, table_path);

            if ((a.database.operation) && (strcmp(a.database.operation, "drop") == 0))
            {
                cfPS(cf_error, CF_FAIL, "", pp, a,
                     "Cfengine will not promise to repair this, as the operation is potentially too destructive.");
                // Future allow deletion?
            }

            retval = false;
        }
    }

    CfDeleteQuery(cfdb);

/* Now look for deviations - only if we have promised to create missing */

    if ((a.database.operation) && (strcmp(a.database.operation, "drop") == 0))
    {
        return retval;
    }

    if (count != no_of_cols)
    {
        for (i = 0; i < no_of_cols; i++)
        {
            if (!done[i])
            {
                CfOut(cf_error, "", " !! Promised column \"%s\" missing from database table %s", name_table[i],
                      pp->promiser);

                if ((!DONTDO) && ((a.transaction.action) != cfa_warn))
                {
                    if (size_table[i] > 0)
                    {
                        snprintf(query, CF_MAXVARSIZE - 1, "ALTER TABLE %s ADD %s %s(%d)", table, name_table[i],
                                 type_table[i], size_table[i]);
                    }
                    else
                    {
                        snprintf(query, CF_MAXVARSIZE - 1, "ALTER TABLE %s ADD %s %s", table, name_table[i],
                                 type_table[i]);
                    }

                    CfVoidQueryDB(cfdb, query);
                    cfPS(cf_error, CF_CHG, "", pp, a, " !! Adding promised column \"%s\" to database table %s",
                         name_table[i], table);
                    retval = true;
                }
                else
                {
                    cfPS(cf_error, CF_WARN, "", pp, a,
                         " !! Promised column \"%s\" missing from database table %s but only a warning was promised",
                         name_table[i], table);
                    retval = false;
                }
            }
        }
    }

    DeleteSQLColumns(name_table, type_table, size_table, done, no_of_cols);

    return retval;
}
Пример #11
0
void inits() {

	errno = 0;

	logfile.open(LOGFILEPATH, std::fstream::out | std::fstream::app);

	logger << "RasPiProg logging started." << endl;

	sa.sa_handler = &sighandler;
	sa.sa_flags = SA_RESTART;
	sigfillset(&sa.sa_mask);

	if(sigaction(SIGTERM, &sa, NULL) == -1) {
		logger << "Error: cannot handle SIGTERM" << endl;
	}

	if(sigaction(SIGHUP, &sa, NULL) == -1) {
		logger << "Error: cannot handle SIGHUP" << endl;
	}

	if(sigaction(SIGUSR1, &sa, NULL) == -1) {
		logger << "Error: cannot handle SIGUSR1" << endl;
	}

	if(sigaction(SIGINT, &sa, NULL) == -1) {
		logger << "Error: cannot handle SIGINT" << endl;
	}

	if(wiringPiSetup() == -1) {
		logger << "WiringPi initialization failed!" << endl;
		exit(1);
	}

	lcdHandle = lcdInit(lcdSettings[0],lcdSettings[1],lcdSettings[2],lcdSettings[3],lcdSettings[4],lcdSettings[5],lcdSettings[6]
			,lcdSettings[7],lcdSettings[8],lcdSettings[9],lcdSettings[10],lcdSettings[11],lcdSettings[12]);

	if(lcdHandle < 0) {
		logger << "LCD-display initialization failed!" << endl;
		exit(2);
	}

	lcdClear(lcdHandle);
	lcdPosition(lcdHandle, 0, 0) ; lcdPuts(lcdHandle, "RasPiProg       By PTapioK");

	sleep(1);

	lcdClear(lcdHandle);

	/*
	int lirc = lirc_init(sqlDBname, 1);

	if(lirc == -1) {
		logger << "Lirc initialization failed!" << endl;
		exit(3);
	}

	if(lirc_readconfig(NULL, &config, NULL) == -1) {
		logger << "Lirc initialization failed!" << endl;
		exit(4);
	}

	// Don't wait IR signals
	fcntl(lirc, F_SETOWN, getpid());
	int flags = fcntl(lirc, F_GETFL, 0);
	if (flags == -1)
		deinits();
	fcntl(lirc, F_SETFL, flags | O_NONBLOCK);
	*/

	sqlCon = mysql_init(NULL);

	if(sqlCon == NULL) {
		logger << "MySQL initialization failed!" << endl;
		exit(5);
	}

	if(mysql_real_connect(sqlCon, sqlHost.c_str(), sqlUsername.c_str(), sqlPassword.c_str(), sqlDBname.c_str(), 0, NULL, 0) == NULL) {
		// Try again
		if(mysql_real_connect(sqlCon, sqlHost.c_str(), sqlUsername.c_str(), sqlPassword.c_str(), sqlDBname.c_str(), 0, NULL, 0) == NULL) {
			logger << "MySQL connection initialization failed!" << endl;
			mysql_close(sqlCon);
			exit(6);
		}
	}

	if(!TableExists(sqlDBname, "temps")) {
		if(mysql_query(sqlCon, "CREATE TABLE temps(id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, name TEXT, st TIMESTAMP DEFAULT CURRENT_TIMESTAMP, temp FLOAT)")) {
			logger << "MySQL error! Errno: " << mysql_errno(sqlCon) << endl;
			mysql_close(sqlCon);
			exit(8);
		}
	}

	if(!TableExists(sqlDBname, "humis")) {
		if(mysql_query(sqlCon, "CREATE TABLE humis(id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, name TEXT, st TIMESTAMP DEFAULT CURRENT_TIMESTAMP, humi FLOAT)")) {
			logger << "MySQL error! Errno: " << mysql_errno(sqlCon) << endl;
			mysql_close(sqlCon);
			exit(8);
		}
	}

	if(!TableExists(sqlDBname, "presss")) {
		if(mysql_query(sqlCon, "CREATE TABLE presss(id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, name TEXT, st TIMESTAMP DEFAULT CURRENT_TIMESTAMP, press FLOAT)")) {
			logger << "MySQL error! Errno: " << mysql_errno(sqlCon) << endl;
			mysql_close(sqlCon);
			exit(8);
		}
	}

	if(!TableExists(sqlDBname, "latestrecords")) {
		if(mysql_query(sqlCon, "CREATE TABLE latestrecords(name VARCHAR(30), type VARCHAR(6), st TIMESTAMP DEFAULT CURRENT_TIMESTAMP, data FLOAT, PRIMARY KEY (name, type))")) {
			logger << "MySQL error! Errno: " << mysql_errno(sqlCon) << endl;
			mysql_close(sqlCon);
			exit(8);
		}
	}

	if(mysql_query(sqlCon, "SET CHARACTER SET utf8")) {
		logger << "MySQL error! Errno: " << mysql_errno(sqlCon) << endl;
		mysql_close(sqlCon);
		exit(10);
	}

/*
	if(mcp3004Setup(BASE, SPI_CHAN) == -1) {
		logger << "MCP3008 chip initialization failed!" << endl;
		exit(7);
	}
*/
	if ((i2cfile = open(I2CBus, O_RDWR)) < 0) {
		logger << endl;
		logger << "Failed to open the i2c bus! Errno: " << errno << endl;
		logger << endl;
		exit(11);
	}

	// Pin 20 is DHT22 power pin.
	pinMode(20, OUTPUT);
	digitalWrite(20, HIGH);
	sleep(5);
}
Пример #12
0
static int VerifyTablePromise(EvalContext *ctx, CfdbConn *cfdb, char *table_path, Rlist *columns, const Attributes *a,
                              const Promise *pp, PromiseResult *result)
{
    assert(a != NULL);
    char name[CF_MAXVARSIZE], type[CF_MAXVARSIZE], query[CF_MAXVARSIZE], table[CF_MAXVARSIZE], db[CF_MAXVARSIZE];
    int i, count, size, no_of_cols, *size_table, *done, identified, retval = true;
    char **name_table, **type_table;

    Log(LOG_LEVEL_VERBOSE, "Verifying promised table structure for '%s'", table_path);

    if (!ValidateSQLTableName(table_path, db, table))
    {
        Log(LOG_LEVEL_ERR,
            "The structure of the promiser did not match that for an SQL table, i.e. 'database.table'");
        return false;
    }
    else
    {
        Log(LOG_LEVEL_VERBOSE, "Assuming database '%s' with table '%s'", db, table);
    }

/* Verify the existence of the tables within the database */

    if (!TableExists(cfdb, table))
    {
        Log(LOG_LEVEL_ERR, "The database did not contain the promised table '%s'", table_path);

        if ((a->database.operation) && (strcmp(a->database.operation, "create") == 0))
        {
            if ((!DONTDO) && ((a->transaction.action) != cfa_warn))
            {
                cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_CHANGE, pp, a, "Database.table '%s' doesn't seem to exist, creating",
                     table_path);
                *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE);
                return CreateTableColumns(cfdb, table, columns);
            }
            else
            {
                Log(LOG_LEVEL_WARNING, "Database.table '%s' doesn't seem to exist, but only a warning was promised",
                      table_path);
            }
        }

        return false;
    }

/* Get a list of the columns in the table */

    QueryTableColumns(query, db, table);
    CfNewQueryDB(cfdb, query);

    if (cfdb->maxcolumns != 3)
    {
        cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Could not make sense of the columns");
        *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL);
        CfDeleteQuery(cfdb);
        return false;
    }

/* Assume that the Rlist has been validated and consists of a,b,c */

    count = 0;
    no_of_cols = RlistLen(columns);

    if (!NewSQLColumns(table, columns, &name_table, &type_table, &size_table, &done))
    {
        cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Could not make sense of the columns");
        *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL);
        return false;
    }

/* Obtain columns from the named table - if any */

    while (CfFetchRow(cfdb))
    {
        char *sizestr;

        name[0] = '\0';
        type[0] = '\0';
        size = CF_NOINT;

        strlcpy(name, CfFetchColumn(cfdb, 0), CF_MAXVARSIZE);
        strlcpy(type, CfFetchColumn(cfdb, 1), CF_MAXVARSIZE);
        ToLowerStrInplace(type);
        sizestr = CfFetchColumn(cfdb, 2);

        if (sizestr)
        {
            size = IntFromString(sizestr);
        }

        Log(LOG_LEVEL_VERBOSE, "Discovered database column (%s,%s,%d)", name, type, size);

        if (sizestr && (size == CF_NOINT))
        {
            cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, pp, a,
                 "Integer size of SQL datatype could not be determined or was not specified - invalid promise.");
            DeleteSQLColumns(name_table, type_table, size_table, done, no_of_cols);
            CfDeleteQuery(cfdb);
            return false;
        }

        identified = false;

        for (i = 0; i < no_of_cols; i++)
        {
            if (done[i])
            {
                continue;
            }

            if (strcmp(name, name_table[i]) == 0)
            {
                CheckSQLDataType(type, type_table[i], pp);

                if (size != size_table[i])
                {
                    cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a,
                         "Promised column '%s' in database.table '%s' has a non-matching array size (%d != %d)",
                         name, table_path, size, size_table[i]);
                    *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL);
                }
                else
                {
                    Log(LOG_LEVEL_VERBOSE, "Promised column '%s' in database.table '%s' is as promised", name,
                          table_path);
                }

                count++;
                done[i] = true;
                identified = true;
                break;
            }
        }

        if (!identified)
        {
            cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a,
                 "Column '%s' found in database.table '%s' is not part of its promise.", name, table_path);
            *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL);

            if ((a->database.operation) && (strcmp(a->database.operation, "drop") == 0))
            {
                cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a,
                     "CFEngine will not promise to repair this, as the operation is potentially too destructive.");
                // Future allow deletion?
                *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL);
            }

            retval = false;
        }
    }

    CfDeleteQuery(cfdb);

/* Now look for deviations - only if we have promised to create missing */

    if ((a->database.operation) && (strcmp(a->database.operation, "drop") == 0))
    {
        return retval;
    }

    if (count != no_of_cols)
    {
        for (i = 0; i < no_of_cols; i++)
        {
            if (!done[i])
            {
                Log(LOG_LEVEL_ERR, "Promised column '%s' missing from database table '%s'", name_table[i],
                      pp->promiser);

                if ((!DONTDO) && ((a->transaction.action) != cfa_warn))
                {
                    if (size_table[i] > 0)
                    {
                        snprintf(query, CF_MAXVARSIZE - 1, "ALTER TABLE %s ADD %s %s(%d)", table, name_table[i],
                                 type_table[i], size_table[i]);
                    }
                    else
                    {
                        snprintf(query, CF_MAXVARSIZE - 1, "ALTER TABLE %s ADD %s %s", table, name_table[i],
                                 type_table[i]);
                    }

                    CfVoidQueryDB(cfdb, query);
                    cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_CHANGE, pp, a, "Adding promised column '%s' to database table '%s'",
                         name_table[i], table);
                    *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE);
                    retval = true;
                }
                else
                {
                    cfPS(ctx, LOG_LEVEL_WARNING, PROMISE_RESULT_WARN, pp, a,
                         "Promised column '%s' missing from database table '%s' but only a warning was promised",
                         name_table[i], table);
                    *result = PromiseResultUpdate(*result, PROMISE_RESULT_WARN);
                    retval = false;
                }
            }
        }
    }

    DeleteSQLColumns(name_table, type_table, size_table, done, no_of_cols);

    return retval;
}