mirror of
https://github.com/OpenNebula/one.git
synced 2024-12-22 13:33:52 +03:00
feature #282: Template attributes are now managed by the PoolSQL objects, and then the object has to be updated to write changes to DB.
This commit is contained in:
parent
51bf1d5be0
commit
fa002ca701
@ -18,7 +18,7 @@
|
||||
#define HOST_H_
|
||||
|
||||
#include "PoolSQL.h"
|
||||
#include "Template.h"
|
||||
#include "HostTemplate.h"
|
||||
#include "HostShare.h"
|
||||
#include "ClusterPool.h"
|
||||
|
||||
@ -419,7 +419,7 @@ private:
|
||||
/**
|
||||
* The Host template, holds the Host attributes.
|
||||
*/
|
||||
Template host_template;
|
||||
HostTemplate host_template;
|
||||
|
||||
/**
|
||||
* The Share represents the logical capacity associated with the host
|
||||
|
@ -17,30 +17,22 @@
|
||||
#ifndef HOST_TEMPLATE_H_
|
||||
#define HOST_TEMPLATE_H_
|
||||
|
||||
#include "TemplateSQL.h"
|
||||
#include "Template.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
/**
|
||||
* Host Template class, it represents the attributes of a Host
|
||||
*/
|
||||
class HostTemplate : public TemplateSQL
|
||||
class HostTemplate : public Template
|
||||
{
|
||||
public:
|
||||
HostTemplate(int tid = -1,
|
||||
const char separator = '='):
|
||||
TemplateSQL(table,tid,true,separator,"TEMPLATE"){};
|
||||
HostTemplate() : Template(true,'=',"TEMPLATE"){};
|
||||
|
||||
~HostTemplate(){};
|
||||
|
||||
private:
|
||||
friend class Host;
|
||||
|
||||
static const char * table;
|
||||
|
||||
static const char * db_bootstrap;
|
||||
};
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
|
@ -279,13 +279,13 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the template, adding a new attribute (replacing it if
|
||||
* Adds a new attribute to the template (replacing it if
|
||||
* already defined), the image's mutex SHOULD be locked
|
||||
* @param name of the new attribute
|
||||
* @param value of the new attribute
|
||||
* @return 0 on success
|
||||
*/
|
||||
int update_template_attribute(
|
||||
int replace_template_attribute(
|
||||
const string& name,
|
||||
const string& value)
|
||||
{
|
||||
|
@ -120,32 +120,6 @@ public:
|
||||
return rc;
|
||||
};
|
||||
|
||||
/** Modify an image attribute in the template (Image MUST be locked)
|
||||
* @param image pointer to Image
|
||||
* @param name of the attribute to be changed
|
||||
* @param new value for the attribute
|
||||
* @return 0 on success, -1 otherwise
|
||||
*/
|
||||
int update_template_attribute(
|
||||
Image * image,
|
||||
const string& name,
|
||||
const string& value)
|
||||
{
|
||||
return image->update_template_attribute(name, value);
|
||||
}
|
||||
|
||||
/** Delete an image attribute in the template (Image MUST be locked)
|
||||
* @param image pointer to Image
|
||||
* @param name of the attribute to be removed
|
||||
* @return 0 on success, -1 otherwise
|
||||
*/
|
||||
int remove_attribute(
|
||||
Image * image,
|
||||
const string& name)
|
||||
{
|
||||
return image->remove_template_attribute(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstraps the database table(s) associated to the Image pool
|
||||
*/
|
||||
|
@ -1,130 +0,0 @@
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) */
|
||||
/* */
|
||||
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
|
||||
/* not use this file except in compliance with the License. You may obtain */
|
||||
/* a copy of the License at */
|
||||
/* */
|
||||
/* http://www.apache.org/licenses/LICENSE-2.0 */
|
||||
/* */
|
||||
/* Unless required by applicable law or agreed to in writing, software */
|
||||
/* distributed under the License is distributed on an "AS IS" BASIS, */
|
||||
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
|
||||
/* See the License for the specific language governing permissions and */
|
||||
/* limitations under the License. */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
#ifndef TEMPLATE_SQL_H_
|
||||
#define TEMPLATE_SQL_H_
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "Template.h"
|
||||
#include "SqlDB.h"
|
||||
#include "ObjectSQL.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
/**
|
||||
* SQL Template class, it provides DB support for template objects
|
||||
*/
|
||||
class TemplateSQL : public Template, public ObjectSQL
|
||||
{
|
||||
public:
|
||||
TemplateSQL(
|
||||
const char * _table,
|
||||
int template_id = -1,
|
||||
bool replace = false,
|
||||
const char separator = '=',
|
||||
const char * xml_root = "TEMPLATE"):
|
||||
Template(replace,separator,xml_root),table(_table),id(template_id)
|
||||
{};
|
||||
|
||||
virtual ~TemplateSQL(){};
|
||||
|
||||
protected:
|
||||
|
||||
//Database implementation variables
|
||||
|
||||
const char * table;
|
||||
|
||||
static const char * db_names;
|
||||
|
||||
//Template attributes
|
||||
|
||||
/**
|
||||
* Template unique identification.
|
||||
*/
|
||||
int id;
|
||||
|
||||
/**
|
||||
* Writes the template in the DB
|
||||
* @param db pointer to the database.
|
||||
* @return 0 on success.
|
||||
*/
|
||||
int insert(SqlDB * db);
|
||||
|
||||
/**
|
||||
* Updates the template in the DB
|
||||
* @param db pointer to the database.
|
||||
* @return 0 on success.
|
||||
*/
|
||||
int update(SqlDB *db);
|
||||
|
||||
/**
|
||||
* Reads the template (identified by its id) from the DB
|
||||
* @param db pointer to the database.
|
||||
* @return 0 on success.
|
||||
*/
|
||||
int select(SqlDB *db);
|
||||
|
||||
/**
|
||||
* Removes the template from the DB
|
||||
* @param db pointer to the database.
|
||||
*/
|
||||
int drop(SqlDB *db);
|
||||
|
||||
/**
|
||||
* Execute an INSERT or REPLACE Sql query.
|
||||
* @param db The SQL DB
|
||||
* @param replace Execute an INSERT or a REPLACE
|
||||
* @return 0 one success
|
||||
*/
|
||||
int insert_replace(SqlDB *db, bool replace);
|
||||
|
||||
/**
|
||||
* Removes a template attribute from the DB. If there are multiple
|
||||
* attributes with the same name, only one will be replaced. The
|
||||
* attribute MUST be allocated in the heap.
|
||||
* @param db pointer to the database.
|
||||
* @param attribute pointer to the new attribute.
|
||||
*/
|
||||
int replace_attribute(SqlDB * db, Attribute * attribute);
|
||||
|
||||
/**
|
||||
* Insert a given attribute (MUST be allocated in the heap) in the template
|
||||
* and updates the DB.
|
||||
* @param db pointer to the database.
|
||||
* @param attribute pointer to the new attribute
|
||||
*/
|
||||
int insert_attribute(SqlDB * db, Attribute * attribute);
|
||||
|
||||
/**
|
||||
* Remove a given attribute from the template and the DB.
|
||||
* @param db pointer to the database.
|
||||
* @param name name of the attribute
|
||||
*/
|
||||
int remove_attribute(SqlDB * db, const string& name);
|
||||
|
||||
/**
|
||||
* Callback to recover template attributes (TemplateSQL::select)
|
||||
*/
|
||||
int select_cb(void *nil, int num, char **values, char **names);
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
#endif /*TEMPLATE_SQL_H_*/
|
@ -598,6 +598,28 @@ public:
|
||||
vm_template->get(str,value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new attribute to the template (replacing it if
|
||||
* already defined), the vm's mutex SHOULD be locked
|
||||
* @param name of the new attribute
|
||||
* @param value of the new attribute
|
||||
* @return 0 on success
|
||||
*/
|
||||
int replace_template_attribute(
|
||||
string& name,
|
||||
string& value)
|
||||
{
|
||||
SingleAttribute * sattr;
|
||||
|
||||
vm_template->erase(name);
|
||||
|
||||
sattr = new SingleAttribute(name,value);
|
||||
vm_template->set(sattr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generates a XML string for the template of the VM
|
||||
* @param xml the string to store the XML description.
|
||||
@ -923,43 +945,6 @@ private:
|
||||
return -1;
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates the template of a VM, adding a new attribute (replacing it if
|
||||
* already defined), the vm's mutex SHOULD be locked
|
||||
* @param name of the new attribute
|
||||
* @param value of the new attribute
|
||||
* @return 0 on success
|
||||
*/
|
||||
int update_template_attribute(
|
||||
string& name,
|
||||
string& value)
|
||||
{
|
||||
SingleAttribute * sattr;
|
||||
|
||||
vm_template->erase(name);
|
||||
|
||||
sattr = new SingleAttribute(name,value);
|
||||
vm_template->set(sattr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a new attribute in the template of a VM.
|
||||
* The vm's mutex SHOULD be locked.
|
||||
* @param attribute the new attribute for the template
|
||||
* @return 0 on success
|
||||
*/
|
||||
int insert_template_attribute(Attribute * attribute)
|
||||
{
|
||||
if( attribute == 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
vm_template->set(attribute);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Attribute Parser
|
||||
|
@ -90,22 +90,6 @@ public:
|
||||
// Virtual Machine DB access functions
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Updates the template of a VM, adding a new attribute (replacing it if
|
||||
* already defined), the vm's mutex SHOULD be locked
|
||||
* @param vm pointer to the virtual machine object
|
||||
* @param name of the new attribute
|
||||
* @param value of the new attribute
|
||||
* @return 0 on success
|
||||
*/
|
||||
int update_template_attribute(
|
||||
VirtualMachine * vm,
|
||||
string& name,
|
||||
string& value)
|
||||
{
|
||||
return vm->update_template_attribute(name,value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the history record of a VM, the vm's mutex SHOULD be locked
|
||||
* @param vm pointer to the virtual machine object
|
||||
|
@ -335,28 +335,6 @@ private:
|
||||
int vn_drop(SqlDB * db);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Updates the template of a VNW, adding a new attribute (replacing it if
|
||||
* already defined), the VN's mutex SHOULD be locked
|
||||
* @param name of the new attribute
|
||||
* @param value of the new attribute
|
||||
* @return 0 on success
|
||||
*/
|
||||
int update_template_attribute(
|
||||
string& name,
|
||||
string& value)
|
||||
{
|
||||
SingleAttribute * sattr;
|
||||
|
||||
vn_template->erase(name);
|
||||
|
||||
sattr = new SingleAttribute(name,value);
|
||||
vn_template->set(sattr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
//**************************************************************************
|
||||
|
@ -96,22 +96,6 @@ public:
|
||||
*/
|
||||
void authorize_nic(VectorAttribute * nic, AuthRequest * ar);
|
||||
|
||||
/**
|
||||
* Updates the template of a VN, adding a new attribute (replacing it if
|
||||
* already defined), the VN's mutex SHOULD be locked
|
||||
* @param vn pointer to the virtual network object
|
||||
* @param name of the new attribute
|
||||
* @param value of the new attribute
|
||||
* @return 0 on success
|
||||
*/
|
||||
int update_template_attribute(
|
||||
VirtualNetwork * vn,
|
||||
string& name,
|
||||
string& value)
|
||||
{
|
||||
return vn->update_template_attribute(name,value);
|
||||
};
|
||||
|
||||
/**
|
||||
* Bootstraps the database table(s) associated to the VirtualNetwork pool
|
||||
*/
|
||||
|
@ -41,7 +41,7 @@ Host::Host(
|
||||
tm_mad_name(_tm_mad_name),
|
||||
last_monitored(0),
|
||||
cluster(ClusterPool::DEFAULT_CLUSTER_NAME),
|
||||
host_template(true,'=',"TEMPLATE")
|
||||
host_template()
|
||||
{};
|
||||
|
||||
|
||||
|
@ -1,24 +0,0 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) */
|
||||
/* */
|
||||
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
|
||||
/* not use this file except in compliance with the License. You may obtain */
|
||||
/* a copy of the License at */
|
||||
/* */
|
||||
/* http://www.apache.org/licenses/LICENSE-2.0 */
|
||||
/* */
|
||||
/* Unless required by applicable law or agreed to in writing, software */
|
||||
/* distributed under the License is distributed on an "AS IS" BASIS, */
|
||||
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
|
||||
/* See the License for the specific language governing permissions and */
|
||||
/* limitations under the License. */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#include "HostTemplate.h"
|
||||
|
||||
const char * HostTemplate::table = "host_attributes";
|
||||
|
||||
const char * HostTemplate::db_bootstrap = "CREATE TABLE IF NOT EXISTS "
|
||||
"host_attributes (id INTEGER, name VARCHAR(256), type INTEGER, value TEXT, "
|
||||
"PRIMARY KEY(id,name))";
|
||||
|
@ -25,7 +25,6 @@ source_files=[
|
||||
'Host.cc',
|
||||
'HostShare.cc',
|
||||
'HostPool.cc',
|
||||
'HostTemplate.cc',
|
||||
'ClusterPool.cc',
|
||||
]
|
||||
|
||||
|
@ -254,9 +254,9 @@ public:
|
||||
CPPUNIT_ASSERT( img != 0 );
|
||||
|
||||
// Image object should be cached. Let's change some template attributes
|
||||
ip->update_template_attribute(img, description_name, new_description);
|
||||
ip->update_template_attribute(img, attr_name, new_attr_value);
|
||||
ip->remove_attribute(img, "ORIGINAL_PATH");
|
||||
img->replace_template_attribute(description_name, new_description);
|
||||
img->replace_template_attribute(attr_name, new_attr_value);
|
||||
img->remove_template_attribute("ORIGINAL_PATH");
|
||||
|
||||
ip->update(img);
|
||||
|
||||
|
@ -100,7 +100,12 @@ void RequestManager::ImageRemoveAttribute::execute(
|
||||
goto error_image_get;
|
||||
}
|
||||
|
||||
rc = ImageRemoveAttribute::ipool->remove_attribute(image, name);
|
||||
rc = image->remove_template_attribute(name);
|
||||
|
||||
if(rc == 0)
|
||||
{
|
||||
rc = ImageRemoveAttribute::ipool->update(image);
|
||||
}
|
||||
|
||||
if ( rc < 0 )
|
||||
{
|
||||
|
@ -101,7 +101,7 @@ void RequestManager::ImageUpdate::execute(
|
||||
goto error_image_get;
|
||||
}
|
||||
|
||||
rc = ImageUpdate::ipool->update_template_attribute(image, name, value);
|
||||
rc = image->replace_template_attribute(name, value);
|
||||
|
||||
if(rc == 0)
|
||||
{
|
||||
|
@ -37,7 +37,6 @@ if env['parsers']=='yes':
|
||||
# Sources to generate the library
|
||||
source_files=[
|
||||
'Template.cc',
|
||||
'TemplateSQL.cc',
|
||||
'template_parser.c',
|
||||
'template_syntax.cc'
|
||||
]
|
||||
|
@ -1,361 +0,0 @@
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) */
|
||||
/* */
|
||||
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
|
||||
/* not use this file except in compliance with the License. You may obtain */
|
||||
/* a copy of the License at */
|
||||
/* */
|
||||
/* http://www.apache.org/licenses/LICENSE-2.0 */
|
||||
/* */
|
||||
/* Unless required by applicable law or agreed to in writing, software */
|
||||
/* distributed under the License is distributed on an "AS IS" BASIS, */
|
||||
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
|
||||
/* See the License for the specific language governing permissions and */
|
||||
/* limitations under the License. */
|
||||
/* -------------------------------------------------------------------------*/
|
||||
|
||||
#include "TemplateSQL.h"
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
/* ************************************************************************ */
|
||||
/* SQL Template */
|
||||
/* ************************************************************************ */
|
||||
|
||||
const char * TemplateSQL::db_names = "(id,name,type,value)";
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int TemplateSQL::insert(SqlDB * db)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if ( id == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = insert_replace(db, false);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int TemplateSQL::update(SqlDB * db)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = insert_replace(db, true);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int TemplateSQL::insert_replace(SqlDB *db, bool replace)
|
||||
{
|
||||
multimap<string,Attribute *>::iterator it;
|
||||
ostringstream oss;
|
||||
int rc;
|
||||
string * attr;
|
||||
char * sql_attr;
|
||||
Attribute::AttributeType atype;
|
||||
|
||||
for(it=attributes.begin(),oss.str("");
|
||||
it!=attributes.end();
|
||||
it++,oss.str(""))
|
||||
{
|
||||
if ( it->second == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
attr = it->second->marshall();
|
||||
atype = it->second->type();
|
||||
|
||||
if ( attr == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
sql_attr = db->escape_str((*attr).c_str());
|
||||
|
||||
delete attr;
|
||||
|
||||
if ( sql_attr == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if(replace)
|
||||
{
|
||||
oss << "REPLACE";
|
||||
}
|
||||
else
|
||||
{
|
||||
oss << "INSERT";
|
||||
}
|
||||
|
||||
oss << " INTO " << table << " " << db_names
|
||||
<< " VALUES (" << id << ",'" << it->first << "',"<< atype <<",'"
|
||||
<< sql_attr << "')";
|
||||
|
||||
rc = db->exec(oss);
|
||||
|
||||
db->free_str(sql_attr);
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
goto error_sql;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error_sql:
|
||||
drop(db);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int TemplateSQL::select_cb(void *nil, int num, char **values, char **names)
|
||||
{
|
||||
Attribute * attr;
|
||||
|
||||
string name;
|
||||
string value;
|
||||
int atype;
|
||||
|
||||
if (num != 4)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( values[1] != 0 )
|
||||
{
|
||||
name = values[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( values[3] != 0 )
|
||||
{
|
||||
value = values[3];
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( values[2] != 0 )
|
||||
{
|
||||
atype = atoi(values[2]);
|
||||
|
||||
switch (atype)
|
||||
{
|
||||
case Attribute::SIMPLE:
|
||||
attr = new SingleAttribute(name);
|
||||
break;
|
||||
|
||||
case Attribute::VECTOR:
|
||||
attr = new VectorAttribute(name);
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
attr->unmarshall(value);
|
||||
|
||||
set(attr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int TemplateSQL::select(SqlDB * db)
|
||||
{
|
||||
ostringstream oss;
|
||||
int rc;
|
||||
|
||||
if ( id == -1 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
set_callback(static_cast<Callbackable::Callback>(&TemplateSQL::select_cb));
|
||||
|
||||
oss << "SELECT * FROM " << table << " WHERE id=" << id;
|
||||
|
||||
rc = db->exec(oss,this);
|
||||
|
||||
unset_callback();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int TemplateSQL::drop(SqlDB * db)
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
if ( id == -1 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
oss << "DELETE FROM " << table << " WHERE id=" << id;
|
||||
|
||||
return db->exec(oss);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int TemplateSQL::replace_attribute(SqlDB * db, Attribute * attribute)
|
||||
{
|
||||
ostringstream oss;
|
||||
int rc;
|
||||
|
||||
multimap<string, Attribute *>::iterator i;
|
||||
|
||||
if ( id == -1 || attribute == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = remove_attribute(db, attribute->name());
|
||||
|
||||
if (rc == 0)
|
||||
{
|
||||
rc = insert_attribute(db,attribute);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int TemplateSQL::insert_attribute(SqlDB * db, Attribute * attribute)
|
||||
{
|
||||
ostringstream oss;
|
||||
int rc;
|
||||
string * astr;
|
||||
int atype;
|
||||
|
||||
char * sql_attr;
|
||||
|
||||
if ( id == -1 || attribute == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
astr = attribute->marshall();
|
||||
atype = attribute->type();
|
||||
|
||||
if ( astr == 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
sql_attr = db->escape_str((*astr).c_str());
|
||||
|
||||
delete astr;
|
||||
|
||||
if ( sql_attr == 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
oss << "INSERT INTO " << table << " " << db_names
|
||||
<< " VALUES (" << id << ",'" << attribute->name() << "'," << atype
|
||||
<< ",'" << sql_attr << "')";
|
||||
|
||||
rc = db->exec(oss);
|
||||
|
||||
db->free_str(sql_attr);
|
||||
|
||||
if (rc == 0)
|
||||
{
|
||||
attributes.insert(make_pair(attribute->name(),attribute));
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int TemplateSQL::remove_attribute(SqlDB * db, const string& name)
|
||||
{
|
||||
ostringstream oss;
|
||||
int rc;
|
||||
string * astr;
|
||||
char * sql_attr;
|
||||
|
||||
multimap<string, Attribute *>::iterator i;
|
||||
|
||||
if ( id == -1 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
i = attributes.find(name);
|
||||
|
||||
if ( i != attributes.end() )
|
||||
{
|
||||
astr = i->second->marshall();
|
||||
|
||||
if ( astr == 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
sql_attr = db->escape_str((*astr).c_str());
|
||||
|
||||
delete astr;
|
||||
|
||||
if ( sql_attr == 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
oss << "DELETE FROM " << table << " WHERE id=" << id
|
||||
<< " AND name='" << name << "' AND value='"
|
||||
<< sql_attr << "'";
|
||||
|
||||
rc = db->exec(oss);
|
||||
|
||||
db->free_str(sql_attr);
|
||||
|
||||
if (rc != 0 )
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
delete i->second;
|
||||
|
||||
attributes.erase(i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
@ -43,7 +43,6 @@ main_env.Append(LIBPATH=[
|
||||
cwd + '/src/common',
|
||||
cwd + '/src/template',
|
||||
cwd + '/src/nebula',
|
||||
cwd + '/src/sql',
|
||||
cwd + '/src/log',
|
||||
])
|
||||
|
||||
@ -51,7 +50,6 @@ main_env.Append(LIBS=[
|
||||
'nebula_template',
|
||||
'nebula_common',
|
||||
'nebula_core',
|
||||
'nebula_sql',
|
||||
'nebula_log',
|
||||
'cppunit',
|
||||
'dl',
|
||||
@ -67,21 +65,5 @@ main_env.Append(CPPFLAGS=[
|
||||
# libxml2
|
||||
main_env.ParseConfig('xml2-config --libs --cflags')
|
||||
|
||||
# MYSQL
|
||||
main_env.Append(LIBPATH=["/usr/lib/mysql"])
|
||||
main_env.Append(CPPPATH=["/usr/include/mysql"])
|
||||
|
||||
sqlite=ARGUMENTS.get('sqlite', 'yes')
|
||||
if sqlite=='yes':
|
||||
main_env.Append(CPPFLAGS=["-DSQLITE_DB"])
|
||||
main_env.Append(LIBS=[ 'sqlite3', ])
|
||||
|
||||
# MySQL
|
||||
mysql=ARGUMENTS.get('mysql', 'no')
|
||||
if mysql=='yes':
|
||||
main_env.Append(CPPFLAGS=["-DMYSQL_DB"])
|
||||
main_env.Append(LIBS=[ 'mysqlclient', ])
|
||||
|
||||
main_env.Program('test','template.cc')
|
||||
main_env.Program('test_sql','template_sql.cc')
|
||||
#
|
||||
|
@ -1,470 +0,0 @@
|
||||
#include "TemplateSQL.h"
|
||||
#include "SqliteDB.h"
|
||||
#include "SqlDB.h"
|
||||
#include "MySqlDB.h"
|
||||
#include "Log.h"
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include <TestFixture.h>
|
||||
#include <TestAssert.h>
|
||||
#include <TestSuite.h>
|
||||
#include <TestCaller.h>
|
||||
#include <ui/text/TestRunner.h>
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
/* ************************************************************************* */
|
||||
/* ************************************************************************* */
|
||||
/* ************************************************************************* */
|
||||
|
||||
/* --------------------------------------- */
|
||||
/* WRAPPER TO ACCESS TEMPLATESQL CLASS */
|
||||
/* --------------------------------------- */
|
||||
|
||||
class TSQL : public TemplateSQL
|
||||
{
|
||||
public:
|
||||
TSQL(const char * _table,
|
||||
int template_id = -1,
|
||||
bool replace = false,
|
||||
const char separator = '=',
|
||||
const char * xml_root = "TEMPLATE"):
|
||||
TemplateSQL(_table,template_id,replace,separator,xml_root){}
|
||||
|
||||
~TSQL(){}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
int insert(SqlDB * db){return TemplateSQL::insert(db);}
|
||||
int update(SqlDB * db){return TemplateSQL::update(db);}
|
||||
int select(SqlDB * db){return TemplateSQL::select(db);}
|
||||
int drop (SqlDB * db){return TemplateSQL::drop(db);}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
int replace_attribute(SqlDB * db, Attribute * attr)
|
||||
{return TemplateSQL::replace_attribute(db,attr);}
|
||||
int insert_attribute(SqlDB * db, Attribute * attr)
|
||||
{return TemplateSQL::insert_attribute(db,attr);}
|
||||
int remove_attribute(SqlDB * db, const string& name)
|
||||
{return TemplateSQL::remove_attribute(db,name);};
|
||||
/* --------------------------------------------------------------------- */
|
||||
int id(){return TemplateSQL::id;};
|
||||
void sid(int i){TemplateSQL::id = i;}
|
||||
};
|
||||
|
||||
/* ************************************************************************* */
|
||||
/* ************************************************************************* */
|
||||
/* ************************************************************************* */
|
||||
|
||||
class TemplateSQLTest : public CppUnit::TestFixture
|
||||
{
|
||||
|
||||
CPPUNIT_TEST_SUITE (TemplateSQLTest);
|
||||
|
||||
CPPUNIT_TEST (test_insert);
|
||||
CPPUNIT_TEST (test_update);
|
||||
CPPUNIT_TEST (test_select);
|
||||
CPPUNIT_TEST (test_drop);
|
||||
CPPUNIT_TEST (test_replace_attribute);
|
||||
CPPUNIT_TEST (test_insert_attribute);
|
||||
CPPUNIT_TEST (test_remove_attribute);
|
||||
|
||||
CPPUNIT_TEST_SUITE_END ();
|
||||
|
||||
private:
|
||||
SqlDB *db;
|
||||
|
||||
string db_name;
|
||||
|
||||
string template_ok;
|
||||
string template_xml;
|
||||
|
||||
public:
|
||||
// Global flag to use either Sqlite or MySQL
|
||||
static bool mysql;
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
TemplateSQLTest()
|
||||
{
|
||||
db_name = "ONE_test_database";
|
||||
|
||||
template_ok =
|
||||
"#This line is a comment\n"
|
||||
" # Other comment\n"
|
||||
"MEMORY=345 # more comments behind an attribute\n"
|
||||
" CPU = 4\n"
|
||||
"#------------------------------\n"
|
||||
"#Comments in the middle\n"
|
||||
"#------------------------------\n"
|
||||
" empty_var = \n"
|
||||
"REQUIREMENTS = \"HOSTNAME = \\\"host*.com\\\"\"\n"
|
||||
" DISK= [file = path1, extra = \"disk attribute \"]\n"
|
||||
"DISK =[ FILE = \"path2\", EXTRA = str, TYPE=disk]\n"
|
||||
" graphics = [\n"
|
||||
" VNC = \"127.0.0.1\",\n"
|
||||
" PORT = 12\n"
|
||||
" ]\n";
|
||||
|
||||
template_xml =
|
||||
"<TEMPLATE><CPU><![CDATA[4]]></CPU><DISK><EXTRA><![CDATA[disk attribute ]]></EXTRA><FILE><![CDATA[path1]]></FILE></DISK><DISK><EXTRA><![CDATA[str]]></EXTRA><FILE><![CDATA[path2]]></FILE><TYPE><![CDATA[disk]]></TYPE></DISK><EMPTY_VAR><![CDATA[]]></EMPTY_VAR><GRAPHICS><PORT><![CDATA[12]]></PORT><VNC><![CDATA[127.0.0.1]]></VNC></GRAPHICS><MEMORY><![CDATA[345]]></MEMORY><REQUIREMENTS><![CDATA[HOSTNAME = \"host*.com\"]]></REQUIREMENTS></TEMPLATE>";
|
||||
}
|
||||
|
||||
~TemplateSQLTest(){};
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
void setUp()
|
||||
{
|
||||
if (mysql)
|
||||
{
|
||||
db = new MySqlDB("localhost","oneadmin","oneadmin",NULL);
|
||||
|
||||
ostringstream oss1;
|
||||
oss1 << "DROP DATABASE IF EXISTS " << db_name;
|
||||
db->exec(oss1);
|
||||
|
||||
ostringstream oss;
|
||||
oss << "CREATE DATABASE " << db_name;
|
||||
db->exec(oss);
|
||||
|
||||
ostringstream oss2;
|
||||
oss2 << "use " << db_name;
|
||||
db->exec(oss2);
|
||||
}
|
||||
else
|
||||
{
|
||||
unlink(db_name.c_str());
|
||||
|
||||
db = new SqliteDB(db_name);
|
||||
}
|
||||
|
||||
ostringstream db_bs(
|
||||
"CREATE TABLE IF NOT EXISTS template (id INTEGER, "
|
||||
"name TEXT, type INTEGER, value TEXT)");
|
||||
|
||||
CPPUNIT_ASSERT(db->exec(db_bs) == 0);
|
||||
}
|
||||
|
||||
void tearDown()
|
||||
{
|
||||
if (mysql)
|
||||
{
|
||||
ostringstream oss;
|
||||
oss << "DROP DATABASE IF EXISTS " << db_name;
|
||||
db->exec(oss);
|
||||
}
|
||||
else
|
||||
{
|
||||
unlink(db_name.c_str());
|
||||
}
|
||||
|
||||
if( db != 0 )
|
||||
delete db;
|
||||
}
|
||||
|
||||
/* ********************************************************************* */
|
||||
/* ********************************************************************* */
|
||||
|
||||
void test_insert()
|
||||
{
|
||||
char * error = 0;
|
||||
int rc;
|
||||
string tmp;
|
||||
TSQL t("template");
|
||||
|
||||
rc = t.parse(template_ok,&error);
|
||||
|
||||
if ( error != 0 )
|
||||
{
|
||||
cerr << error << endl;
|
||||
free(error);
|
||||
}
|
||||
|
||||
CPPUNIT_ASSERT( rc == 0);
|
||||
|
||||
t.sid(0);
|
||||
CPPUNIT_ASSERT( t.insert(db) == 0 );
|
||||
CPPUNIT_ASSERT( t.id() == 0 );
|
||||
|
||||
t.sid(1);
|
||||
CPPUNIT_ASSERT( t.insert(db) == 0 );
|
||||
CPPUNIT_ASSERT( t.id() == 1 );
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
void test_update()
|
||||
{
|
||||
int rc;
|
||||
string att_name = "NEW_ATT";
|
||||
string value = "";
|
||||
|
||||
ostringstream db_bs(
|
||||
"CREATE TABLE IF NOT EXISTS template_replace (id INTEGER, "
|
||||
"name VARCHAR(256), type INTEGER, value TEXT, PRIMARY KEY(id,name))");
|
||||
|
||||
CPPUNIT_ASSERT(db->exec(db_bs) == 0);
|
||||
|
||||
TSQL t ("template_replace",0);
|
||||
TSQL t2("template_replace",0);
|
||||
|
||||
// Insert template t into the DB
|
||||
t.insert(db);
|
||||
|
||||
// Add a new vector attribute to t, and insert it into the DB
|
||||
SingleAttribute * s_att = new SingleAttribute(att_name, "some value");
|
||||
t.insert_attribute(db, ((Attribute*)s_att));
|
||||
|
||||
|
||||
// Now replace the attribute's value
|
||||
s_att->replace("a new value");
|
||||
|
||||
// And update the DB
|
||||
t.update(db);
|
||||
|
||||
// Read from the DB to t2
|
||||
rc = t2.select(db);
|
||||
CPPUNIT_ASSERT( rc == 0 );
|
||||
|
||||
t2.get(att_name, value);
|
||||
CPPUNIT_ASSERT( value == "a new value" );
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
void test_select()
|
||||
{
|
||||
char * error = 0;
|
||||
|
||||
TSQL t("template");
|
||||
TSQL t2("template",23);
|
||||
|
||||
string t2_xml;
|
||||
|
||||
t.sid(23);
|
||||
t.parse(template_ok,&error);
|
||||
|
||||
int rc = t.insert(db);
|
||||
CPPUNIT_ASSERT( rc == 0 );
|
||||
|
||||
if ( error != 0 )
|
||||
{
|
||||
free(error);
|
||||
}
|
||||
|
||||
CPPUNIT_ASSERT( t2.select(db) == 0 );
|
||||
|
||||
t2.to_xml(t2_xml);
|
||||
|
||||
CPPUNIT_ASSERT( t2_xml == template_xml );
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
void test_drop()
|
||||
{
|
||||
char * error = 0;
|
||||
string str = "";
|
||||
|
||||
TSQL t ("template",0);
|
||||
TSQL t2("template",0);
|
||||
|
||||
t.parse(template_ok,&error);
|
||||
t.insert(db);
|
||||
|
||||
if ( error != 0 )
|
||||
{
|
||||
free(error);
|
||||
}
|
||||
|
||||
// Drop the template from the DB
|
||||
t.drop(db);
|
||||
|
||||
// Try to read it from the DB
|
||||
CPPUNIT_ASSERT( t2.select(db) == 0 );
|
||||
// It should be empty
|
||||
CPPUNIT_ASSERT( t2.to_str(str) == "" );
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
void test_replace_attribute()
|
||||
{
|
||||
int rc;
|
||||
string att_name = "NEW_ATT";
|
||||
string value = "";
|
||||
|
||||
|
||||
TSQL t ("template",0);
|
||||
TSQL t2("template",0);
|
||||
|
||||
// Add a new vector attribute to t, and insert it into the DB
|
||||
VectorAttribute * v_att = new VectorAttribute(att_name);
|
||||
v_att->replace("A", "A value");
|
||||
v_att->replace("B", "B value");
|
||||
v_att->replace("C", "C value");
|
||||
|
||||
t.insert(db);
|
||||
t.insert_attribute(db, ((Attribute*)v_att));
|
||||
|
||||
|
||||
|
||||
// Now replace its value, with a single value attribute
|
||||
SingleAttribute * s_att = new SingleAttribute(att_name, "some value");
|
||||
|
||||
t.replace_attribute(db, ((Attribute*)s_att) );
|
||||
|
||||
|
||||
// Read from the DB to t2
|
||||
rc = t2.select(db);
|
||||
CPPUNIT_ASSERT( rc == 0 );
|
||||
|
||||
t2.get(att_name, value);
|
||||
CPPUNIT_ASSERT( value == "some value" );
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
void test_insert_attribute()
|
||||
{
|
||||
Attribute * att;
|
||||
int rc;
|
||||
string att_name = "NEW_ATT";
|
||||
string value = "";
|
||||
|
||||
|
||||
TSQL t ("template",0);
|
||||
TSQL t2("template",0);
|
||||
|
||||
// Add a new attribute to t, and insert it into the DB
|
||||
att = new SingleAttribute(att_name, "some value");
|
||||
|
||||
t.insert(db);
|
||||
t.insert_attribute(db, att);
|
||||
|
||||
// Read from the DB to t2
|
||||
rc = t2.select(db);
|
||||
CPPUNIT_ASSERT( rc == 0 );
|
||||
|
||||
t2.get(att_name, value);
|
||||
CPPUNIT_ASSERT( value == "some value" );
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
void test_remove_attribute()
|
||||
{
|
||||
Attribute * att;
|
||||
int rc;
|
||||
string att_name = "NEW_ATT";
|
||||
string value = "";
|
||||
|
||||
|
||||
TSQL t ("template",0);
|
||||
TSQL t2("template",0);
|
||||
|
||||
// Add a new attribute to t, and insert it into the DB
|
||||
att = new SingleAttribute(att_name, "some value");
|
||||
|
||||
t.insert(db);
|
||||
t.insert_attribute(db, att);
|
||||
|
||||
t.remove_attribute(db, att_name);
|
||||
|
||||
// Read from the DB to t2
|
||||
rc = t2.select(db);
|
||||
CPPUNIT_ASSERT( rc == 0 );
|
||||
|
||||
t2.get(att_name, value);
|
||||
CPPUNIT_ASSERT( value == "" );
|
||||
}
|
||||
};
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
||||
bool TemplateSQLTest::mysql;
|
||||
|
||||
/* ************************************************************************* */
|
||||
/* ************************************************************************* */
|
||||
/* ************************************************************************* */
|
||||
|
||||
static void show_options ()
|
||||
{
|
||||
cout << "Options:\n";
|
||||
cout << " -h --help Show this help\n"
|
||||
" -s --sqlite Run Sqlite tests (default)\n"
|
||||
" -m --mysql Run MySQL tests\n"
|
||||
" -l --log Keep the log file, test.log\n";
|
||||
}
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
|
||||
// Option flags
|
||||
bool sqlite_flag = true;
|
||||
bool log_flag = false;
|
||||
|
||||
// Long options
|
||||
const struct option long_opt[] =
|
||||
{
|
||||
{ "sqlite", 0, NULL, 's'},
|
||||
{ "mysql", 0, NULL, 'm'},
|
||||
{ "log", 0, NULL, 'l'},
|
||||
{ "help", 0, NULL, 'h'}
|
||||
};
|
||||
|
||||
int c;
|
||||
while ((c = getopt_long (argc, argv, "smlh", long_opt, NULL)) != -1)
|
||||
switch (c)
|
||||
{
|
||||
case 'm':
|
||||
sqlite_flag = false;
|
||||
break;
|
||||
case 'l':
|
||||
log_flag = true;
|
||||
break;
|
||||
case 'h':
|
||||
show_options();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
CppUnit::TextUi::TestRunner tr;
|
||||
|
||||
tr.addTest(TemplateSQLTest::suite());
|
||||
|
||||
NebulaLog::init_log_system(NebulaLog::FILE, Log::DEBUG, "test.log");
|
||||
NebulaLog::log("Test", Log::INFO, "Test started");
|
||||
|
||||
|
||||
if (sqlite_flag)
|
||||
{
|
||||
TemplateSQLTest::mysql = false;
|
||||
NebulaLog::log("Test", Log::INFO, "Running Sqlite tests...");
|
||||
cout << "\nRunning Sqlite tests...\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
TemplateSQLTest::mysql = true;
|
||||
NebulaLog::log("Test", Log::INFO, "Running MySQL tests...");
|
||||
cout << "\nRunning MySQL tests...\n";
|
||||
}
|
||||
|
||||
|
||||
tr.run();
|
||||
|
||||
|
||||
if (!log_flag)
|
||||
remove("test.log");
|
||||
|
||||
NebulaLog::finalize_log_system();
|
||||
|
||||
return 0;
|
||||
}
|
@ -237,7 +237,7 @@ public:
|
||||
vm->set_state(VirtualMachine::ACTIVE);
|
||||
|
||||
// VirtualMachine object should be cached. Let's update the DB
|
||||
vmp->update_template_attribute(vm, attribute, value);
|
||||
vm->replace_template_attribute(attribute, value);
|
||||
|
||||
vmp->update(vm);
|
||||
|
||||
|
@ -517,7 +517,7 @@ void VirtualMachineManagerDriver::protocol(
|
||||
|
||||
tiss >> val;
|
||||
|
||||
vmpool->update_template_attribute(vm,var,val);
|
||||
vm->replace_template_attribute(var,val);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user