Disable automatic index on related object id from yml - symfony1

Doctrine Automatically creates indexes on columns that are used to define object relations,
For example
user: id, name
message: id, sender_id, receiver_id, message
if I define relationship between message and user in a way that message has one Sender and has one Receiver, doctrine will automatically index sender_id and receiver_id fields when I generate sql from model. I would like to disable index on sender, because I manually create index with sender_id and receiver id together. How can I disable auto generated index?

Hello I assumed you were using MySQL, and took a look in Doctrine/Export/Mysql.php
I found this :
// build indexes for all foreign key fields (needed in MySQL!!)
if (isset($options['foreignKeys'])) {
foreach ($options['foreignKeys'] as $fk) {
$local = $fk['local'];
$found = false;
if (isset($options['indexes'])) {
foreach ($options['indexes'] as $definition) {
if (is_string($definition['fields'])) {
// Check if index already exists on the column
$found = $found || ($local == $definition['fields']);
} else if (in_array($local, $definition['fields']) && count($definition['fields']) === 1) {
// Index already exists on the column
$found = true;
}
}
}
if (isset($options['primary']) && !empty($options['primary']) &&
in_array($local, $options['primary'])) {
// field is part of the PK and therefore already indexed
$found = true;
}
if ( ! $found) {
if (is_array($local)) {
foreach($local as $localidx) {
$options['indexes'][$localidx] = array('fields' => array($localidx => array()));
}
} else {
$options['indexes'][$local] = array('fields' => array($local => array()));
}
}
}
}
If I understand correctly, to disable the index should be part of the primary key.

Related

Find all instances of a type associated with another type

I have some classes that look like this:
class User {
boolean enabled
String username
}
class ExampleClass {
User firstUser
User secondUser
}
My end goal is to find all instances of User where enabled == true OR the instance of User is associated with ExampleClass.
Where this code is running I don't have access to the variable names firstUser or secondUser.
With that said, I need to be able to find all instance of User associated with ExampleClass, disregarding which variable (firstUser or secondUser) the association was made through. How do I do this?
UPDATE:
The best I can come up with is this method in my User domain class. I the example I gave above I have an ExampleClass which has multiple fields of the User type. In fact I have multiple classes with multiple fields of the User type. This is why I get the domain class from the object being passed in instead of just typing ExampleClass.
static List findAllEnabledOrAssociatedWith( Object obj = null ) {
if( obj?.id ) { // Make sure the object in question has been saved to database.
List list = []
obj.domainClass.getPersistentProperties().each {
if( it.getReferencedPropertyType() == User ) {
def propertyName = it.getName()
list += User.executeQuery( "SELECT DISTINCT ${propertyName} FROM ${obj.class.getSimpleName()} obj INNER JOIN obj.${propertyName} ${propertyName} WHERE obj =:obj", [ obj: obj ] )
}
}
list.unique()
return User.executeQuery( "SELECT DISTINCT users FROM User users WHERE users.enabled=true OR users IN(:list)", [ list: list ] )
} else {
return User.executeQuery( "SELECT DISTINCT users FROM User users WHERE users.enabled=true" )
}
}
def sql = '''
from
User u,
ExampleClass ex
where
u.enabled = 1 or (u = ex.firstUser or u = ex.secondUser)'''
def users = User.findAll(sql)

How to cache aggregate column values on Doctrine_Record instance?

Lets say i have a record class that often gets queried with dyanmic colums that are MySQL aggregate values:
$results = Doctrine_Core::getTable('MyRecord')->creatQuery('m')
->select('m.*, AVG(m.rating) as avg_rating, SUM(m.id) as nb_related')
->innerJoin('m.AnotherRecords a')
->where('m.id = ?')
->fetchOne();
Now lets say i want a method on that record to check if the aggregate columns exist from when the record was queried, and if not then i want to go ahead an issue a separate query to get these values:
// this doesnt actually work because of filterSet and filterGet
// but its general idea
public function getAverageRating($wtihNbRelated = false)
{
if(!isset($this->avg_rating) || ($withNbRelated && !isset($this->nb_related))
{
$rating = $this->getTable()->getAverageRating($this, $withNbRelated);
$this->avg_rating = $rating['avg_rating'];
if($withNbRealted)
{
$this->nb_related = $rating['nb_related'];
}
}
return $withNbRelated
? array('avg_rating' => $this->avg_rating, 'nb_related' => $this->nb_related)
: array('avg_rating' => $this->avg_rating);
}
Is there an easy way (ie. not writing a custom hydrator) to do this?
Simple answer really. I forgot that Doctrine prefixes all its direct protected members with _. So, even though i initially tried manipulating the data member i was forgot the prefix giving me the same result as if i tried $this->avg_rating or its accessor method. The solution was:
public function getAverageRating($wtihNbRelated = false)
{
if(!isset($this->_data['avg_rating']) || ($withNbRelated && !isset($this->_data['nb_related']))
{
$rating = $this->getTable()->getAverageRating($this, $withNbRelated);
$this->_data['avg_rating'] = $rating['avg_rating'];
if($withNbRealted)
{
$this->_data['nb_related'] = $rating['nb_related'];
}
}
return $withNbRelated
? array('avg_rating' => $this->_data['avg_rating'], 'nb_related' => $this->_data['nb_related'])
: array('avg_rating' => $this->_data['avg_rating']);
}

ASP.Net MVC : Get query values with no key

I have URL: http://site.com/page.aspx?update
how do I check if that update value is present?
HttpValueCollection treats that as an entity with null key. I have tried:
var noKeyValues = Request.QueryString.GetValues(null);
if (noKeyValues != null && noKeyValues.Any(v=>v==update)) ...
but it gives me a frowny line, because GetValues' argument is decorated with [NotNull].
so I end up doing:
var queryValuesWithNoKey =
Request.QueryString.AllKeys.Select((key, index) => new { key, value = Request.QueryString.GetValues(index) }).Where(
item => item.key == null).Select(item => item.value).SingleOrDefault();
if (queryValuesWithNoKey != null && queryValuesWithNoKey.Any(v => v.ToLower() == "update")) live = true;
not the most elegant workaround. Is there a better way to get key-less value from query string?
You can use
Request.QueryString[null]
to retrieve a comma separated list of keys with no values. For instance, if your url is:
http://mysite/?first&second
then the above will return
first,second
In your case, you could just do something like:
if(Request.QueryString[null] == "update")
{
// it's an update
}
if that's the only key you would use
Request.QueryString.ToString() to get the "update" value
I know I'm late to the party, but this a function that I use for this kind of task.
internal static bool HasQueryStringKey(HttpRequestBase request, string key)
{
// If there isn't a value, ASP will not recognize variable / key names.
string[] qsParts = request.QueryString.ToString().Split('&');
int qsLen = qsParts.Length;
for (int i = 0; i < qsLen; i++)
{
string[] bits = qsParts[i].Split('=');
if (bits[0].Equals(key, StringComparison.OrdinalIgnoreCase))
{
return true;
}
}
return false;
}
You may need to update it so that it is case sensitive, or uses different arguments depending on your purposes, but this has always worked well for me.

symfony: how to loop through fields of Doctrine object

I need to loop through a list of fields in a custom validator to compare the value against a value already stored in the database.
My code here:
$healthUser = PersonTable::getInstance->getHealthUser(trim($values['nhi']));
if ($healthUser->getNHI() == trim($values['nhi']) &&
$healthUser->getName() != trim($values['name'])){
//Also loop through all fields and show differences
foreach (array('suite','hnr_street','suburb','city','postcode','postal_address')
as $field){
if ($value[$field] != $healthUser->getFieldName()){
//How do I get the field name from $field?--^^^^^^^^^^
$errorSchemaLocal->addError(new sfValidatorError($this,
'fieldIsDifferent', $healthUser->getFieldName()),
$field);
}
}
SO basically i need to create the getter function from the field name in $field.
Any idea how to do this?
Doctrine record implements ArrayAccess interface. You can simply access the record as an array:
if ($value[$field] != $healthUser[$field]) {
// ...
}
You can also use sfInflector to construct a getter name:
$getField = sprintf('get%s'), ucfirst(sfInflector::cammelize($field)));
if ($value[$field] != $healthUser->$getField()) {
// ...
}

Remove Dropdownlist Value

I am working in MVC2. Here i had Employee Screen. There itself i am having a dropdown list. In that all the Employee Names will loaded. The Employee profile which i am viewing should not be loaded in the dropdown list. I should remove the particular Employee from the dropdown list. Here is my code for loading dropdown...How to do this...
Dictionary<string, Employee> Employee1 = new Dictionary<string, EmployeeDetails>();
Employee1 = EmployeeProxy.GetPrimaryEmployeeList(UserIdentity.TenantID);
List<EmployeeDetails> managerDetailsList = Employee1.Values.ToList();
if (managerDetailsList != null && managerDetailsList.Count > 0)
{
managerDetailsList.Sort(delegate(EmployeeDetails p1, EmployeeDetails p2) { return p1.FirstName.CompareTo(p2.FirstName); });
}
foreach (EmployeeDetails employeedetails in managerDetailsList)
{
employeedetails.FirstName = employeedetails.FirstName + " " + employeedetails.LastName;
}
RobinHood,
Simply change this line:
List<EmployeeDetails> managerDetailsList = Employee1.Values.ToList();
to:
List<EmployeeDetails> managerDetailsList = Employee1.Values.Where(x => x.ID != Employee1.ID).ToList();
assuming that such an attribute (ID) exists. Basically, what i'm saying is that from the managerDetailsList, exclude the Employee1 member (based on the assumption that Employee1.Values is IQueryable).

Resources