Exemplo n.º 1
0
bool DBObject::find(long long objectId)
{
	MutexLocker lock(_mutex);

	if (_connection == NULL)
	{
		ERROR_MSG("Object is not connected to the database.");
		return false;
	}

	if (objectId == 0) {
		ERROR_MSG("Invalid object_id 0 passed to find");
		return false;
	}

	// find the object in the database for the given object_id
	DB::Statement statement = _connection->prepare(
				"select id from object where id=%lld",
				objectId);
	if (!statement.isValid()) {
		ERROR_MSG("Preparing object selection statement failed");
		return false;
	}

	DB::Result result = _connection->perform(statement);
	if (result.getLongLong(1) != objectId) {
		ERROR_MSG("Failed to find object with id %lld",objectId);
		return false;
	}

	_objectId = objectId;
	return true;
}
Exemplo n.º 2
0
void test_a_db_with_a_connection_with_tables::will_not_insert_non_existing_attribute_on_update()
{
	DB::Statement statement;
	DB::Result result;

	// Insert new object
	statement = connection->prepare(
				"insert into object default values");
	CPPUNIT_ASSERT(statement.isValid());
	CPPUNIT_ASSERT(connection->execute(statement));
	long long object_id = connection->lastInsertRowId();
	CPPUNIT_ASSERT(object_id != 0);

	// Updating an attribute before it is created will succeed, but will not insert an attribute.
	statement = connection->prepare(
				"update attribute_boolean set value=1 where type=%d and object_id=%lld",
				1237,
				object_id);
	CPPUNIT_ASSERT(statement.isValid());
	CPPUNIT_ASSERT(connection->execute(statement));

	// Retrieve the boolean value from the attribute should fail
	statement = connection->prepare(
				"select value from attribute_boolean as t where t.type=%d and t.object_id=%lld",
				1237,
				object_id);
	CPPUNIT_ASSERT(statement.isValid());
	result = connection->perform(statement);
	CPPUNIT_ASSERT(!result.isValid());
}
Exemplo n.º 3
0
void test_a_db_with_a_connection_with_tables::can_update_text_attribute_bound_value()
{
	can_insert_records();

	// query all objects
	DB::Statement statement = connection->prepare("select id from object");
	CPPUNIT_ASSERT(statement.isValid());
	DB::Result result = connection->perform(statement);
	CPPUNIT_ASSERT(result.isValid());

	long long object_id = result.getLongLong(1); // field indices start at 1

	statement = connection->prepare(
				"update attribute_text set value=? where type=%d and object_id=%lld",
				1234,
				object_id);
	CPPUNIT_ASSERT(statement.isValid());

	std::string msg("testing quote ' and accents é.");

	CPPUNIT_ASSERT(DB::Bindings(statement).bindText(1,msg.c_str(),msg.size(),NULL));
	CPPUNIT_ASSERT(connection->execute(statement));

	statement = connection->prepare(
				"select value from attribute_text as t where t.type=%d and t.object_id=%lld",
				1234,
				object_id);
	result = connection->perform(statement);
	CPPUNIT_ASSERT_EQUAL(std::string(result.getString(1)), msg);
}
Exemplo n.º 4
0
void test_a_db_with_a_connection_with_tables::can_update_integer_attribute_bound_value()
{
	// insert new object
	DB::Statement statement = connection->prepare(
				"insert into object default values");
	CPPUNIT_ASSERT(statement.isValid());
	CPPUNIT_ASSERT(connection->execute(statement));
	long long object_id = connection->lastInsertRowId();
	CPPUNIT_ASSERT(object_id != 0);

	// insert integer attribute
	statement = connection->prepare(
				"insert into attribute_integer (value,type,object_id) values (%lld,%d,%lld)",
				1111,
				1235,
				object_id);
	CPPUNIT_ASSERT(statement.isValid());
	CPPUNIT_ASSERT(connection->execute(statement));

	// prepare update integer attribute statement
	statement = connection->prepare(
				"update attribute_integer set value=? where type=%d and object_id=%lld",
				1235,
				object_id);
	CPPUNIT_ASSERT(statement.isValid());

	// bind long long value to the parameter an update the record
	CPPUNIT_ASSERT(DB::Bindings(statement).bindInt64(1,2222));
	CPPUNIT_ASSERT(connection->execute(statement));

	// Retrieve the value from the record
	DB::Statement retrieveStmt = connection->prepare(
				"select value from attribute_integer as t where t.type=%d and t.object_id=%lld",
				1235,
				object_id);
	CPPUNIT_ASSERT(retrieveStmt.isValid());
	DB::Result result = connection->perform(retrieveStmt);
	CPPUNIT_ASSERT_EQUAL(result.getLongLong(1), (long long)2222);

	// verify that binding to a parameter before resetting the statement will fail.
	DB::LogErrorHandler eh = DB::setLogErrorHandler(dummy_print);
	DB::Bindings bindings(statement);
	CPPUNIT_ASSERT(!bindings.bindInt(1,3333));
	DB::setLogErrorHandler(eh);

	// reset statement and bind another value to the statement
	CPPUNIT_ASSERT(bindings.reset());
	CPPUNIT_ASSERT(bindings.bindInt(1,3333));

	// perform the update statement again with the newly bound value
	CPPUNIT_ASSERT(connection->execute(statement));

	// reset the retrieve statement and perform it again to get the latest value of the integer attribute
	CPPUNIT_ASSERT(retrieveStmt.reset());
	result = connection->perform(retrieveStmt);
	CPPUNIT_ASSERT(result.isValid());
	CPPUNIT_ASSERT_EQUAL(result.getLongLong(1), (long long)3333);
}
Exemplo n.º 5
0
void test_a_db_with_a_connection::can_perform_statements()
{
	DB::Statement statement = connection->prepare("PRAGMA database_list;");
	CPPUNIT_ASSERT(statement.isValid());
	DB::Result result = connection->perform(statement);
	CPPUNIT_ASSERT(result.isValid());
	// only expect a single row in the result, so nextRow should now fail
	CPPUNIT_ASSERT(!result.nextRow());
}
Exemplo n.º 6
0
void test_a_db_with_a_connection_with_tables::can_retrieve_records()
{
	can_insert_records();

	DB::Statement statement = connection->prepare(
				"select value from attribute_text as t where t.type=%d",
				1234);
	DB::Result result = connection->perform(statement);
	CPPUNIT_ASSERT_EQUAL(std::string(result.getString(1)), std::string("testing testing testing"));
}
Exemplo n.º 7
0
std::vector<Event> Event::select(std::string cond, int limit){
    DB::Result r = DB::query("SELECT type, source_id, source_name, target_id, target_name, track_id, track_title, message, date AT TIME ZONE 'UTC', id FROM events" + (cond.empty()?"":" WHERE "+cond) + " ORDER BY date DESC" + (limit?" LIMIT "+number(limit):""));
    std::vector<Event> events(r.size());
    for(unsigned i=0; i<r.size(); i++){
        Type t = r[i][0] == "publish"  ? Publish
             : r[i][0] == "comment"  ? Comment
             : r[i][0] == "favorite" ? Favorite : Follow;
        events[i] = Event(t, User(number(r[i][1]),r[i][2]), User(number(r[i][3]),r[i][4]), Track(number(r[i][5]),r[i][6]), r[i][7], r[i][8], number(r[i][9]));
    }
    return events;
}
Exemplo n.º 8
0
void test_a_db_with_a_connection_with_tables::can_update_boolean_attribute_bound_value()
{
	//SQLite doesn't have a boolean data type, use 0 (false) and 1 (true)

	DB::Statement statement;
	DB::Result result;

	// Insert new object
	statement = connection->prepare(
				"insert into object default values");
	CPPUNIT_ASSERT(statement.isValid());
	CPPUNIT_ASSERT(connection->execute(statement));
	long long object_id = connection->lastInsertRowId();
	CPPUNIT_ASSERT(object_id != 0);

	// insert boolean attribute
	statement = connection->prepare(
				"insert into attribute_boolean (value,type,object_id) values (1,%d,%lld)",
				1237,
				object_id);
	CPPUNIT_ASSERT(statement.isValid());
	CPPUNIT_ASSERT(connection->execute(statement));

	// prepare update boolean attribute statement
	statement = connection->prepare(
				"update attribute_boolean set value=? where type=%d and object_id=%lld",
				1237,
				object_id);
	CPPUNIT_ASSERT(statement.isValid());

	// Bind 0 (false) to the first parameter
	CPPUNIT_ASSERT(DB::Bindings(statement).bindInt(1,0));

	// Execute the statement to update the attribute value.
	CPPUNIT_ASSERT(connection->execute(statement));

	// Retrieve the boolean value from the attribute
	statement = connection->prepare(
				"select value from attribute_boolean as t where t.type=%d and t.object_id=%lld",
				1237,
				object_id);
	CPPUNIT_ASSERT(statement.isValid());
	result = connection->perform(statement);
	CPPUNIT_ASSERT(result.isValid());

	// check that the retrieved value matches the original value
	CPPUNIT_ASSERT_EQUAL(result.getInt(1), 0);
}
Exemplo n.º 9
0
void Pages::registration(Document *doc){

    if(path != "/register")
        return;

    std::string name = cgi("name"), email = cgi("email"), pw = cgi("pw");

    if(Session::user())
        doc->redirect("/");

    else if(cgi.getEnvironment().getRequestMethod() != "POST")
        form(doc);

    else if(name.empty())
        form(doc, "Please specify a display name.");

    else if(email.empty())
        form(doc, "Please specify an email address.");
    else if(!validEmail(email))
        form(doc, "Invalid email address.");

    else if(pw.empty())
        form(doc, "Please specify a password.");
    else if(pw != cgi("pwconf"))
        form(doc, "Passwords mismatch.");

    else{

        if(DB::query("SELECT EXISTS (SELECT 1 FROM users WHERE lower(name) = lower($1) OR lower(email) = lower($2))", name, email)[0][0] == "t")
            return form(doc, "Sorry, name or email already in use.");

        DB::Result r = DB::query(
            "INSERT INTO users (name, password, email, registration, last_login) "
            "VALUES ($1, crypt($2, gen_salt('bf')), $3, 'now', 'now') "
            "RETURNING id", name, pw, email);

        if(r.empty())
            return form(doc, "Erm, something went wrong. Please try again.");

        User u = User(number(r[0][0]), name);
        log("New user: "******" (" + number(u.id) + ")");
        doc->addHttp("Set-Cookie: sid=" + Session::login(u) + ";Max-Age=2592000\n"); // 30 days
        doc->redirect(u.url() + "?welcome=1");

    }

}
Exemplo n.º 10
0
void test_a_db_with_a_connection_with_tables::can_update_blob_attribute_bound_value()
{
	// insert new object
	DB::Statement statement = connection->prepare(
				"insert into object default values");
	CPPUNIT_ASSERT(statement.isValid());
	CPPUNIT_ASSERT(connection->execute(statement));
	long long object_id = connection->lastInsertRowId();
	CPPUNIT_ASSERT(object_id != 0);

	// insert blob attribute
	statement = connection->prepare(
				"insert into attribute_blob (value,type,object_id) values (X'012345',%d,%lld)",
				1236,
				object_id);
	CPPUNIT_ASSERT(statement.isValid());
	CPPUNIT_ASSERT(connection->execute(statement));

	// prepare update blob attribute statement
	statement = connection->prepare(
				"update attribute_blob set value=? where type=%d and object_id=%lld",
				1236,
				object_id);
	CPPUNIT_ASSERT(statement.isValid());

	// bind blob (with embedded zero!) to the parameter
	const char data[] = {10,11,0,12,13,14,15,16};
	std::string msg(data,sizeof(data));
	CPPUNIT_ASSERT(DB::Bindings(statement).bindBlob(1,msg.data(),msg.size(),NULL));

	// update the blob value of the attribute
	CPPUNIT_ASSERT(connection->execute(statement));

	// retrieve the blob value from the attribute
	statement = connection->prepare(
				"select value from attribute_blob as t where t.type=%d and t.object_id=%lld",
				1236,
				object_id);
	CPPUNIT_ASSERT(statement.isValid());
	DB::Result result = connection->perform(statement);
	CPPUNIT_ASSERT(result.isValid());

	// check that the retrieved blob value matches the original data.
	CPPUNIT_ASSERT_EQUAL(result.getFieldLength(1), sizeof(data));
	std::string msgstored((const char *)result.getBinary(1),result.getFieldLength(1));
	CPPUNIT_ASSERT_EQUAL(msg, msgstored);
}
Exemplo n.º 11
0
Track::Track(int tid){

    id = 0;
    if(tid <= 0) return;

    DB::Result r = DB::query(
        "SELECT tracks.title, tracks.user_id, users.name, tracks.visible, tracks.date FROM tracks, users "
        "WHERE tracks.id = " + number(tid) + " AND tracks.user_id = users.id");

    if(!r.empty()){
        id = tid;
        title = r[0][0];
        artist = User(number(r[0][1]), r[0][2]);
        visible = r[0][3] == "t";
        date = r[0][4];
    }

}
Exemplo n.º 12
0
void test_a_db_with_a_connection_with_tables::can_update_real_attribute_bound_value()
{
	// insert new object
	DB::Statement statement = connection->prepare(
				"insert into object default values");
	CPPUNIT_ASSERT(statement.isValid());
	CPPUNIT_ASSERT(connection->execute(statement));
	long long object_id = connection->lastInsertRowId();
	CPPUNIT_ASSERT(object_id != 0);

	// insert real value
	statement = connection->prepare(
				"insert into attribute_real (value,type,object_id) values(%f,%d,%lld)",
				1.238,
				1238,
				object_id);
	CPPUNIT_ASSERT(statement.isValid());
	CPPUNIT_ASSERT(connection->execute(statement));

	// prepare update real attribute statement
	statement = connection->prepare(
				"update attribute_real set value=? where type=%d and object_id=%lld",
				1238,
				object_id);
	CPPUNIT_ASSERT(statement.isValid());

	// Bind 3333.3333 to the first parameter
	CPPUNIT_ASSERT(DB::Bindings(statement).bindDouble(1,3333.3333));

	// Execute the statement to update the attribute value
	CPPUNIT_ASSERT(connection->execute(statement));

	// Retrieve the double value from the attribute
	statement = connection->prepare(
				"select value from attribute_real as t where t.type=%d and t.object_id=%lld",
				1238,
				object_id);
	CPPUNIT_ASSERT(statement.isValid());
	DB::Result result = connection->perform(statement);
	CPPUNIT_ASSERT(result.isValid());

	// check that the retrieved value matches the original value.
	CPPUNIT_ASSERT_DOUBLES_EQUAL(result.getDouble(1), 3333.3333, 0.00001);
}
Exemplo n.º 13
0
ExtendedTrack::ExtendedTrack(int tid){

    id = 0;
    if(tid<=0) return;

    DB::Result r = DB::query(
        "SELECT tracks.title, tracks.user_id, users.name, users.email, tracks.visible, tracks.date, extract(epoch from tracks.date),"
        " tracks.notes, tracks.airable, tracks.license, array_to_string(tracks.tags, ',') FROM tracks, users "
        "WHERE tracks.id = " + number(tid) + " AND tracks.user_id = users.id");

    if(!r.empty()){

        id = tid;
        title = r[0][0];
        artist.id = number(r[0][1]);
        artist.name = r[0][2];
        artist.email = r[0][3];
        visible = r[0][4] == "t";
        date = r[0][5];
        timestamp = r[0][6];

        // Ext
        notes = r[0][7];
        airable = r[0][8] == "t";
        license = r[0][9];

        // Tags
        std::string tstr = r[0][10];
        std::string buf;
        for(std::string::const_iterator i=tstr.begin(); i!=tstr.end(); i++){
            if(*i == ','){
                if(!buf.empty()){
                    tags.push_back(buf);
                    buf.clear();
                }
            }
            else buf += *i;
        }
        if(!buf.empty()) tags.push_back(buf); // last tag

    }

}
Exemplo n.º 14
0
void test_a_db_with_a_connection_with_tables::can_cascade_delete_objects_and_attributes()
{
	can_insert_records();

	DB::Statement statement = connection->prepare("select id from object");
	DB::Result result = connection->perform(statement);
	CPPUNIT_ASSERT(result.isValid());

	long long object_id = result.getLongLong(1);

	statement = connection->prepare("delete from object where id=%lld",object_id);
	CPPUNIT_ASSERT(connection->execute(statement));

	statement = connection->prepare("select * from attribute_text where object_id=%lld",object_id);
	result = connection->perform(statement);

	// Check cascade delete was successful.
	CPPUNIT_ASSERT(!result.isValid());
}
Exemplo n.º 15
0
void test_a_db_with_a_connection_with_tables::can_update_text_attribute()
{
	can_insert_records();

	// query all objects
	DB::Statement statement = connection->prepare("select id from object");
	CPPUNIT_ASSERT(statement.isValid());
	DB::Result result = connection->perform(statement);
	CPPUNIT_ASSERT(result.isValid());

	long long object_id = result.getLongLong(1); // field indices start at 1

	statement = connection->prepare(
				"update attribute_text set value='test test test' where type=%d and object_id=%lld",
				1234,
				object_id);
	CPPUNIT_ASSERT(statement.isValid());
	CPPUNIT_ASSERT(connection->execute(statement));
}
Exemplo n.º 16
0
void test_a_db_with_a_connection_with_tables_with_a_second_connection_open::supports_transactions_with_other_connections_open()
{
	CPPUNIT_ASSERT(connection2->beginTransactionRO());

	supports_transactions();

	// Retrieve the double value from the attribute
	DB::Statement statement = connection2->prepare(
				"select value from attribute_real as t where t.type=%d and t.object_id=%lld",
				1238,
				connection->lastInsertRowId());
	CPPUNIT_ASSERT(statement.isValid());
	DB::Result result = connection2->perform(statement);
	CPPUNIT_ASSERT(result.isValid());

	// check that the retrieved value matches the original value.
	CPPUNIT_ASSERT_DOUBLES_EQUAL(result.getDouble(1), 3333.3333, 0.00001);

	CPPUNIT_ASSERT(connection2->commitTransaction());
}
Exemplo n.º 17
0
int main(int argc, char **argv){
    if(argc != 3){
        cerr << "Usage: nowplaying.json ARTIST TRACK" << endl;
        return 1;
    }
    DB::connect();
    User u(argv[1]);
    std::string tid;
    if(u){
        DB::Result r = DB::query("SELECT id FROM tracks WHERE user_id=" + number(u.id()) + " AND title=$1",argv[2]);
        if(!r.empty()) tid = r[0][0];
    }
    cout << "{";
    if(!tid.empty()) cout << field("id",tid);
    cout << field("title", jstring(argv[2]))
         << field("artist"
            , "{" + (u?field("id",number(u.id())):"") + field("name",jstring(argv[1]),true) + "}"
            , true)
         << "}";
    DB::close();
    return 0;
}
Exemplo n.º 18
0
void test_a_db_with_a_connection::maintains_correct_refcounts()
{
	DB::Statement statement = connection->prepare("PRAGMA database_list;");
	CPPUNIT_ASSERT_EQUAL(statement.refcount(), 1);
	{
		DB::Statement statement1 = statement;
		DB::Statement statement2 = statement;
		CPPUNIT_ASSERT_EQUAL(statement.refcount(), 3);
		CPPUNIT_ASSERT(statement1.isValid());
		CPPUNIT_ASSERT(statement2.isValid());
	}
	CPPUNIT_ASSERT(statement.isValid());
	CPPUNIT_ASSERT_EQUAL(statement.refcount(), 1);

	DB::Result result = connection->perform(statement);
	CPPUNIT_ASSERT(result.isValid());

	// Statement is referenced by the result because it provides the query record cursor state.
	CPPUNIT_ASSERT_EQUAL(statement.refcount(), 2);

	result = DB::Result();
	CPPUNIT_ASSERT_EQUAL(statement.refcount(), 1);
}
Exemplo n.º 19
0
OSAttribute *DBObject::accessAttribute(CK_ATTRIBUTE_TYPE type)
{
	switch (attributeKind(type))
	{
		case akUnknown:
			return NULL;
		case akBoolean:
		{
			// try to find the attribute in the boolean attribute table
			DB::Statement statement = _connection->prepare(
				"select value from attribute_boolean where type=%lu and object_id=%lld",
				type,
				_objectId);
			if (!statement.isValid())
			{
				return NULL;
			}
			DB::Result result = _connection->perform(statement);
			if (!result.isValid())
			{
				return NULL;
			}
			// Store the attribute in the transaction when it is active.
			std::map<CK_ATTRIBUTE_TYPE,OSAttribute*> *attrs = &_attributes;
			if (_transaction)
				attrs = _transaction;

			bool value = result.getInt(1) != 0;
			std::map<CK_ATTRIBUTE_TYPE,OSAttribute*>::iterator it =	 attrs->find(type);
			OSAttribute *attr;
			if (it != attrs->end())
			{
				if (it->second != NULL)
				{
					delete it->second;
				}

				it->second = new OSAttribute(value);
				attr = it->second;
			}
			else
			{
				attr = new OSAttribute(value);
				(*attrs)[type] = attr;
			}
			return attr;
		}
		case akInteger:
		{
			// try to find the attribute in the integer attribute table
			DB::Statement statement = _connection->prepare(
				"select value from attribute_integer where type=%lu and object_id=%lld",
				type,
				_objectId);
			if (!statement.isValid())
			{
				return NULL;
			}
			DB::Result result = _connection->perform(statement);
			if (!result.isValid())
			{
				return NULL;
			}
			// Store the attribute in the transaction when it is active.
			std::map<CK_ATTRIBUTE_TYPE,OSAttribute*> *attrs = &_attributes;
			if (_transaction)
				attrs = _transaction;

			unsigned long value = result.getULongLong(1);
			std::map<CK_ATTRIBUTE_TYPE,OSAttribute*>::iterator it =	 attrs->find(type);
			OSAttribute *attr;
			if (it != attrs->end())
			{
				if (it->second != NULL)
				{
					delete it->second;
				}

				it->second = new OSAttribute(value);
				attr = it->second;
			}
			else
			{
				attr = new OSAttribute(value);
				(*attrs)[type] = attr;
			}
			return attr;
		}
		case akBinary:
		{
			// try to find the attribute in the binary attribute table
			DB::Statement statement = _connection->prepare(
				"select value from attribute_binary where type=%lu and object_id=%lld",
				type,
				_objectId);
			if (!statement.isValid())
			{
				return NULL;
			}
			DB::Result result = _connection->perform(statement);
			if (!result.isValid())
			{
				return NULL;
			}
			// Store the attribute in the transaction when it is active.
			std::map<CK_ATTRIBUTE_TYPE,OSAttribute*> *attrs = &_attributes;
			if (_transaction)
				attrs = _transaction;

			const unsigned char *value = result.getBinary(1);
			size_t size = result.getFieldLength(1);
			std::map<CK_ATTRIBUTE_TYPE,OSAttribute*>::iterator it =	 attrs->find(type);
			OSAttribute *attr;
			if (it != attrs->end())
			{
				if (it->second != NULL)
				{
					delete it->second;
				}

				it->second = new OSAttribute(ByteString(value,size));
				attr = it->second;
			}
			else
			{
				attr = new OSAttribute(ByteString(value,size));
				(*attrs)[type] = attr;
				return attr;
			}
			return attr;
		}
		case akMechSet:
		{
			// try to find the attribute in the binary attribute table
			DB::Statement statement = _connection->prepare(
					"select value from attribute_binary where type=%lu and object_id=%lld",
					type,
					_objectId);
			if (!statement.isValid())
			{
				return NULL;
			}
			DB::Result result = _connection->perform(statement);
			if (!result.isValid())
			{
				return NULL;
			}
			// Store the attribute in the transaction when it is active.
			std::map<CK_ATTRIBUTE_TYPE,OSAttribute*> *attrs = &_attributes;
			if (_transaction)
				attrs = _transaction;

			const unsigned char *value = result.getBinary(1);
			size_t size = result.getFieldLength(1);

			std::set<CK_MECHANISM_TYPE> set;
			if (!decodeMechanismTypeSet(set, value, size))
			{
				return NULL;
			}

			OSAttribute *attr;
			std::map<CK_ATTRIBUTE_TYPE,OSAttribute*>::iterator it =	 attrs->find(type);
			if (it != attrs->end())
			{
				if (it->second != NULL)
				{
					delete it->second;
				}

				it->second = new OSAttribute(set);
				attr = it->second;
			}
			else
			{
				attr = new OSAttribute(set);
				(*attrs)[type] = attr;
				return attr;
			}
			return attr;
		}
		case akAttrMap:
		{
			// try to find the attribute in the array attribute table
			DB::Statement statement = _connection->prepare(
				"select value from attribute_array where type=%lu and object_id=%lld",
				type,
				_objectId);
			if (!statement.isValid())
			{
				return NULL;
			}
			DB::Result result = _connection->perform(statement);
			if (!result.isValid())
			{
				return NULL;
			}
			// Store the attribute in the transaction when it is active.
			std::map<CK_ATTRIBUTE_TYPE,OSAttribute*> *attrs = &_attributes;
			if (_transaction)
				attrs = _transaction;

			const unsigned char *binary = result.getBinary(1);
			size_t size = result.getFieldLength(1);
			std::map<CK_ATTRIBUTE_TYPE,OSAttribute*>::iterator it =	 attrs->find(type);
			OSAttribute *attr;
			if (it != attrs->end())
			{
				std::map<CK_ATTRIBUTE_TYPE,OSAttribute> value;
				if (!decodeAttributeMap(value,binary,size))
				{
					return NULL;
				}

				if (it->second != NULL)
				{
					delete it->second;
				}

				it->second = new OSAttribute(value);
				attr = it->second;
			}
			else
			{
				std::map<CK_ATTRIBUTE_TYPE,OSAttribute> value;
				if (!decodeAttributeMap(value,binary,size))
				{
					return NULL;
				}
				attr = new OSAttribute(value);
				(*attrs)[type] = attr;
				return attr;
			}
			return attr;
		}
	}

	return NULL;
}
Exemplo n.º 20
0
void Pages::passwordReset(Document *doc){

    if(path != "/account/reset")
        return;

    if(Session::user())
        doc->redirect("/account");

    // Coming from an email

    if(!cgi("token").empty()){
        DB::Result r = DB::query("SELECT user_id FROM resets WHERE token = $1", cgi("token"));

        if(r.empty())
            form(doc, "Sorry, looks like your token has expired. You could always try again.");

        else{
            DB::query("DELETE FROM resets WHERE token = $1", cgi("token"));
            std::string pw = randomString(16);
            int uid = number(r[0][0]);

            Account a(uid);
            DB::query("UPDATE users SET password = crypt($1, gen_salt('bf')) WHERE id = " + number(a.id), pw);
            std::string sid = Session::login(a);

            doc->setHtml("html/account.tpl", "Your account");
            doc->addHttp("Set-Cookie: sid=" + sid + ";Max-Age=2592000;Path=/\n"); // 30 days
            doc->dict()->SetValueAndShowSection("MESSAGE", "Your password has been reset to " + pw + ". You can now change it below.", "MESSAGE");
            doc->dict()->SetValue("OLD_PASSWORD", pw);
            a.fill(doc->dict());
        }

    }

    // Sending the token

    else if(cgi.getEnvironment().getRequestMethod() == "POST" && !cgi("email").empty()){
        DB::Result r = DB::query("SELECT id FROM users WHERE lower(email) = lower($1)", cgi("email"));

        if(r.empty())
            form(doc, "Sorry, we couldn't find any account with this email address. Try again?");

        else{
            std::string token = randomString(32);
            while(DB::query("INSERT INTO resets (user_id, token) VALUES ($1, $2) RETURNING 1", r[0][0], token).empty())
                token = randomString(32);

            sendMail(cgi("email").c_str(),
                ((std::string)"From: EqBeats <*****@*****.**>\n"
                "Subject: Resetting your password on EqBeats\n\n"
                "Hi.\n\n"
                "Someone, hopefully you, requested a password reset on your account at EqBeats. "
                "If you want to reset your password, please click this link : " + eqbeatsUrl() + "/account/reset?token=" + token + "\n"
                "If you didn't request it, please ignore this email.\n\n"
                "Cheers.").c_str());

            doc->setHtml("html/password-reset.tpl", "Password reset");
            doc->dict()->SetValueAndShowSection("MESSAGE",
                "A reset link has been sent to your email address. "
                "If there's any more problems (can't access your email, etc...), "
                "feel free to drop us a line at [email protected].", "MESSAGE");
        }

    }

    // Not coming from a form nor an email
    else
        form(doc);

}
Exemplo n.º 21
0
void Pages::track(Document *doc){

    std::string sub;
    int tid = route("track", path, sub);
    bool post = cgi.getEnvironment().getRequestMethod() == "POST";

    if(!tid) return;

    if(sub == ""){

        ExtendedTrack t(tid);
        if(!t) return;

        doc->setHtml("html/track.tpl", t.title);

        doc->rootDict()->SetValueAndShowSection("TID", number(t.id), "HAS_OEMBED");
        t.fill(doc->dict());
        t.player(doc->dict(), true);
        Audio(&t).fill(doc->dict());

        doc->dict()->ShowSection(Youtube(t.artist.id) ? "HAS_YOUTUBE" : "NO_YOUTUBE");

        Dict *embed = doc->dict()->AddIncludeDictionary("EMBED_CODE");
        embed->SetFilename("html/embed-code.tpl");
        embed->SetIntValue("WIDTH", 150);
        t.Track::fill(embed);

        Dict *uploader = doc->dict()->AddIncludeDictionary("UPLOADER");
        uploader->SetFilename("html/uploader.tpl");
        uploader->SetValue("ACTION", t.url() + "/upload");

        int hits = Stat::push("trackView", t.artist.id, tid);
        doc->dict()->SetValue("HIT_COUNT", number(hits));
        int unique_hits = Stat::get("trackView", 0, tid, true);
        doc->dict()->SetValue("UNIQUE_HIT_COUNT", number(unique_hits));
        doc->rootDict()->ShowSection("REQUIRES_STATS_JS");

        Session::fill(doc->dict());
        EventList::track(t).fill(doc->dict(), "EVENTS", false);
        doc->dict()->ShowSection(Follower(Session::user().id).favorited(tid) ? "IS_FAVORITE" : "NOT_FAVORITE");

        if(Session::user()){
            DB::Result playlists = DB::query(
                "SELECT id, name FROM playlists WHERE user_id = " + number(Session::user().id) + " ORDER BY name ASC");
            if(!playlists.empty()){
                doc->dict()->ShowSection("HAS_PLAYLISTS");
                for(DB::Result::const_iterator i=playlists.begin(); i!=playlists.end(); i++){
                    Dict *playlist = doc->dict()->AddSectionDictionary("PLAYLIST");
                    playlist->SetValue("PLAYLIST_ID", i->at(0));
                    playlist->SetValue("PLAYLIST_NAME", i->at(1));
                }
            }
        }
    }

    else if(sub == "delete"){
        Track t(tid);
        if(!t) return;
        if(!t.artist.self())
            doc->redirect(t.url());

        else if(!post || cgi("confirm") != "Delete" || Session::nonce() != cgi("nonce")){
            Session::newNonce();
            doc->setHtml("html/delete.tpl", "Track deletion");
            doc->dict()->SetValue("WHAT", t.title);
            doc->dict()->SetValue("CANCEL_URL", t.url());
        }

        else{
            log("Deleting track: " + t.title + " (" + number(t.id) + ")");

            Art art(t.id);
            if(art) art.remove();
            Audio(&t).unlink();

            Playlist::removeTrack(t.id);
            DB::query("DELETE FROM events WHERE track_id = " + number(t.id));
            DB::query("DELETE FROM featured_tracks WHERE track_id = " + number(t.id));
            DB::query("DELETE FROM favorites WHERE type = 'track' AND ref = " + number(t.id));
            DB::query("DELETE FROM user_features WHERE type = 'track' AND ref = " + number(t.id));
            DB::query("DELETE FROM tracks WHERE id = " + number(t.id));

            doc->redirect(Session::user().url());
        }

    }

    else if(sub == "publish"){
        Track t(tid);
        if(!t) return;
        if(tid != number(cgi("tid")))
            return doc->redirect(t.url());

        if(t.artist.self() && !t.visible && post){

            DB::query("UPDATE tracks SET visible = 't', date = 'now' WHERE id = " + number(t.id));

            Event e;
            e.type = Event::Publish;
            e.source = t.artist;
            e.track = t;
            e.push();

            std::vector<std::string> emails = Follower(t.artist.id).followers();
            std::string maildata =
                "From: EqBeats notification <*****@*****.**>\n"
                "Message-ID: notify-t" + number(t.id) + "\n"
                "Subject: " + filter("EqBeats notification: " + t.artist.name + " - " + t.title) + "\n"
                "Precedence: bulk\n\n" +
                t.artist.name + " just published a new track : " + t.title + "\n"
                "Listen to it here : " + eqbeatsUrl() + t.url() + "\n\n"
                "You're receiving this email because you're following " + t.artist.name + " on EqBeats.\n"
                "If you don't want to receive these notifications anymore, go to " + eqbeatsUrl() + t.artist.url() + " and click \"Stop following\".";
            for(std::vector<std::string>::const_iterator i = emails.begin(); i!=emails.end(); i++)
                sendMail(i->c_str(), maildata.c_str());

        }
        doc->redirect(t.url());

    }

}
Exemplo n.º 22
0
Youtube::operator bool() const {
    DB::Result r = DB::query("SELECT 1 FROM youtube_refresh_tokens WHERE user_id = " + number(_uid) + " LIMIT 1");
    return r.size() > 0;
}