The code
<cfheader name="Test" value="1">
<cfheader name="Test" value="2">
results in the header "Test: 2" being sent to the browser (as seen using HttpFox).
Is there a way for the second line of code to determine if a header with the same name has already been written using CFHEADER?
Thanks!
What version of ColdFusion are you using? When I run your code on ColdFusion 9, I get the header value (As seen using FireBug):
test: 1, 2
As for whether or not you can tell what, if any, existing values there might be for the response header, I haven't yet found a way. I'll keep looking, though.
Update: Found it.
getPageContext().getResponse().containsHeader("test")
For example:
<cfif getPageContext().getResponse().containsHeader("test") eq "NO">
<cfheader name="test" value="2" />
</cfif>
Can't help with exact task of checking the headers, but I'd tried to implement the header facade to handle the headers sending and tracking the history of alredy processed items.
It can be as simple as UDF wrapper, like this one:
<!--- this should be somewhere on request start --->
<cfset request.headers = {} />
<!--- wrapper for cfheader --->
<cffunction name="SendHeader" returntype="void" output="false">
<cfargument name="name" type="string" required="true" hint="Header name">
<cfargument name="value" type="string" required="true" hint="Header value">
<cfif NOT StructKeyExists(request.headers, arguments.name)>
<cfset request.headers[arguments.name] = arguments.value />
<cfheader name="#arguments.name#" value="#arguments.value#" />
</cfif>
</cffunction>
Related
I'm using FOSUserBundle and I've created a Message table with two columns, that are relating to the User from FOSUserBundle.
I want to get messages and information about the author using one query.
Following schema.xml:
<?xml version="1.0" encoding="UTF-8"?>
<database name="default" namespace="Acme\StoreBundle\Model" defaultIdMethod="native">
<table name="message">
<column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true" />
<column name="title" type="varchar" size="64" required="true" defaultValue="(untitled)"/>
<column name="content" type="longvarchar" />
<column name="author_id" type="integer" required="true" />
<foreign-key foreignTable="fos_user">
<reference local="author_id" foreign="id" />
</foreign-key>
<column name="recipient_id" type="integer" required="true" />
<foreign-key foreignTable="fos_user">
<reference local="recipient_id" foreign="id" />
</foreign-key>
</table>
</database>
I was trying many options, with no result.
When I try, what seems to be logical:
$messages = MessageQuery::create()
->join('Message.Authorid')
->findByRecipientId(1);
I get an error: "Unknown table or alias Message"
With:
->join('Authorid')
Error: "Unknown relation Authorid on the Acme\StoreBundle\Model\Message table"
What am I doing wrong?
Thank you for your help.
Ok, I found it out.
The schema for both author and recipient has to look like:
...
<column name="author_id" type="integer" required="true" />
<foreign-key foreignTable="fos_user" phpName="Author">
<reference local="author_id" foreign="id" />
</foreign-key>
<column name="recipient_id" type="integer" required="true" />
<foreign-key foreignTable="fos_user" phpName="Recipient">
<reference local="recipient_id" foreign="id" />
</foreign-key>
...
The important part is the phpName.
Now the controller. And here is something weird that happens, but it doesn't disturb.
$messages = MessageQuery::create()
->find();
return $this->render('AcmeStoreBundle:Message:index.html.twig',
array('messages' => $messages)
);
And after this easy code, I have access to everything from twig.
At this point I'd like to show an example:
When the controller looks like above, then
# AcmeStoreBundle:Message:index.html.twig
messages
Shows every field of the message table like:
Acme\StoreBundle\Model\Message_0: Id: 1 CreatedAt: !!php/object:O:8:"DateTime":3: {s:4:"date";s:19:"2013-03-20 13:00:00";s:13:"timezone_type";i:3;s:8:"timezone";s:12:"Europe/Paris";} Title: (untitled) Content: 'test content' AuthorId: 1 RecipientId: 2 Acme\StoreBundle\Model\Message_1: Id: 2 CreatedAt: !!php/object:O:8:"DateTime":3:{s:4:"date";s:19:"2013-03-20 13:15:22";s:13:"timezone_type";i:3;s:8:"timezone";s:12:"Europe/Paris";} Title: (untitled2) Content: 'bla bla content 2' AuthorId: 2 RecipientId: 1
As you can see, there is nothing about the relationship with author or recipient, but when I call message.author.username, or message.recipient.username (in the for loop of messages) I'm getting this. And this is what I actually expected.
And now when the controller looks like:
$messages = MessageQuery::create()
->joinWith('Author')
->find();
return $this->render('AcmeStoreBundle:Message:index.html.twig',
array('messages' => $messages)
);
messages (in twig) throws all the fields like above, and an author object (called author, not user, because of phpName from the schema).
Thank you guys for reading my question and many thx for participation.
The join method takes the relation using tables or phpName aliases, not the fields. So you probably want:
->join("Message.Author")
Or, as your foreign key suggests, maybe this?
->join("Message.FosUser")
UPDATE
With two FK references to the same table, you will want to use the phpName and refPhpName attributes of the foreign-key tag:
<table name="message">
...
<foreign-key foreignTable="fos_user" phpName="Author" refPhpName="AuthoredMessage">
<reference local="author_id" foreign="id" />
</foreign-key>
<foreign-key foreignTable="fos_user" phpName="Recipient" refPhpName="ReceivedMessage">
<reference local="recipient_id" foreign="id" />
</foreign-key>
</table>
Then you could try using ->join('Message.Author') or ->join('Message.Recipient')
See the documentation of the foreign-key element.
I want to add a file upload html element in my process definition's start even in form.
<startEvent id="start" name="Start">
<extensionElements>
<activiti:formProperty id="name" name="Name"
type="string" required="true" />
<activiti:formProperty id="emailAddress" name="Email Address"
type="string" required="true" />
<activiti:formProperty id="income" name="Income"
type="long" required="true" />
<activiti:formProperty id="loanAmount" name="Loan Amount"
type="long" required="true" />
</extensionElements>
</startEvent>
I want to add a file uploader at the end to take file from user and process it further. I tried using file data type but of no use. Please guide as to how can I add a file element here.
Thanks
Append this for an upload field:
<activiti:formProperty id="attachfile" name="Atatch File"
type="upload" required="true" />
I've got a record I'm editing in a ASP.net web app using nhibernate and MVP. When I make the changes to the record, I need to check to see that one field is unique (see 'friendlyUrl' below). However when I so my Criteria.List call, it updates the record as well as all child records (PharmacyStoreHours) first then does the select (found this out with a SQL profile). Obviously I don't want to update the record before the validation is complete and the validation fails as the data has been updated before the select. How do I do a select without the record updating?
As this is my first project with NHibernate, I'm not sure what would be causing this. I've copied what I've done from other parts of the code so if things look funny, please explain why they are so I can better understand what I should be doing.
NHibernate Config File Class:
<class table="Pharmacy" name="DataAccess.Domains.Pharmacy, DataAccess">
<id name="PharmacyId" column="PharmacyId" unsaved-value="0">
<generator class="increment" />
</id>
<property name="StoreAccountNumber" column="StoreAccountNumber" type="System.String" not-null="true" />
<property name="ClientName" column="ClientName" type="System.String" not-null="true" />
<property name="PharmacyName" column="PharmacyName" type="System.String" not-null="true" />
<property name="Address" column="Address" type="System.String" not-null="false" />
<property name="AddressContinued" column="AddressContinued" type="System.String" not-null="false" />
<property name="City" column="City" type="System.String" not-null="false" />
<property name="State" column="State" type="System.String" not-null="false" />
<property name="Zipcode" column="Zipcode" type="System.String" not-null="false" />
<property name="Phone" column="Phone" type="System.String" not-null="false" />
<property name="Fax" column="Fax" type="System.String" not-null="false" />
<property name="Email" column="Email" type="System.String" not-null="false" />
<property name="FriendlyUrl" column="FriendlyUrl" type="System.String" not-null="false" />
<property name="OwnersName" column="OwnersName" type="System.String" not-null="false" />
<property name="Latitude" column="Latitude" type="System.Decimal" not-null="false" />
<property name="Longitude" column="Longitude" type="System.Decimal" not-null="false" />
<bag name="Hours" table="PharmacyStoreHours" cascade="all" inverse="true">
<key column="PharmacyId" />
<one-to-many class="DataAccess.Domains.PharmacyWorkDays, DataAccess" />
</bag>
</class>
<class table="PharmacyStoreHours" name="DataAccess.Domains.PharmacyWorkDays, DataAccess">
<id name="PharmacyStoreHourId" column="PharmacyStoreHourId" unsaved-value="0">
<generator class="increment" />
</id>
<property name="WorkDay" column="WorkDay" type="System.Int32" not-null="true" />
<property name="OpenTime" column="OpenTime" type="System.DateTime" not-null="true" />
<property name="CloseTime" column="CloseTime" type="System.DateTime" not-null="true" />
<many-to-one name="PharmacyMap" class="DataAccess.Domains.Pharmacy, DataAccess" column="PharmacyId" not-null="true" />
</class>
Code:
public bool IsFriendlyUrlUnique(string clientName, string friendlyUrl)
{
bool result = false;
ICriteria crit = CurrentSession.CreateCriteria(typeof (Pharmacy));
crit.Add(new EqExpression("ClientName", clientName));
crit.Add(new EqExpression("FriendlyUrl", friendlyUrl));
crit.AddOrder(Order.Asc(PHARMACY_NAME));
if (crit.List<Pharmacy>().Count == 0)
result = true;
return result;
}
Thanks in advance for the help.
NHibernate essentially tracks all changes you make to the objects you have attached to your NHibernate session. When you retrieve an object, modifies it and then do a query to the database, NHibernate is faced with a problem. Let say, for argument's sake, that you retrieve a customer from the database, set customer.IsValuedCustomer = true and next query for all valued customers. NHibernate now has (at least) two options:
If NHibernate just translates the query you are doing to SQL and returns the result, the result might not be what you expect, because it will not include the newly promoted customer.
NHibernate can get the correct result by first flushing all the changes you've made to the database and only then executing the SQL query. This, however, means that even though you think you are doing a harmless query, it actually triggers a write to the database.
Based on your description I am not totally sure, but I think that what you are seeing is scenario 2 (btw, Entity Framework has chosen to go with option 1).
You could perhaps do your uniqueness-checking before making any changes to the object. However, this would still leave room for a race condition to occur: just after you checked for uniqueness some other thread might write a change to the database causing your new value to no longer be unique. To circumvent this, you could put the uniqueness constraint straight into your database schema, where it usually belongs.
Hope this helps
Advised Solution
I would advise, in the query, you filter out the current record.
ICriteria crit = CurrentSession.CreateCriteria(typeof (Pharmacy));
crit.Add(Restrictions.Not(Restrictions.Eq("PharmacyId", pharmacyIdToIgnore)));
crit.Add(Restrictions.Eq("ClientName", clientName));
crit.Add(Restrictions.Eq("FriendlyUrl", friendlyUrl));
crit.AddOrder(Order.Asc(PHARMACY_NAME));
crit.SetProjection(Projections.RowCount);
return crit.UniqueResult<int> == 0;
Ideally, you should perform this validation before you alter the entity itself. Also see Rune's answer about placing a constraint in the DB to enforce this constraint. This check is not to prevent duplicates, its to try and detect them earlier so you can present a nicer error message and avoid trying to commit a change that you know will fail.
Why this is happening (FlushMode)
This is on purpose to ensure the results from your query are consistent with the edits you have made locally. Since NHibernate is trying to model your entities as if they are always available in memory by automatically persisting to/from the database as required.
You can change this by looking at the auto flush setting. There is a default value on the session factory used for any newly created sessions, and an individual setting on each session.
The default value is FlushMode.Auto which will save when a transaction is committed or before running any query that might be affected by changes in memory. If you change it to FlushMode.Commit then it will only persist changes back to the database when committing a transaction, or when saving a new entity that uses a primary key strategy such as identity.
You can also manually persist the changes in the current session back to the database at any time using Session.Flush.
I'm calling ColdFusion cfc method using RemoteObject method of the Flex.
<fx:Declarations>
<s:RemoteObject destination="ColdFusion" source="cfc.categoryGateway" id="categoryGateway">
<s:method name="getCategoryList" result="returnHandler(event)"
fault="mx.controls.Alert.show(event.fault.faultString)">
<s:arguments>
<orderby>categoryId</orderby>
<parentCategory>1</parentCategory>
</s:arguments>
</s:method>
</s:RemoteObject>
</fx:Declarations>
Where as my cfc accepts the parameter in following manner:
<cffunction name="getCategoryList" access="remote" output="false" returntype="query">
<cfargument name="parentCategory" type="string" required="false" />
<cfargument name="orderby" type="string" required="false" />
<!--- code... --->
<cfreturn qCategoryList />
</cffunction>
So you can see that I changed the sequence of the parameter, when I call the cfc method. But it does not worked.
It means that <s:arguments> does not pass the named parameter.
Is there any solution for that? As you can see that I may have some of the arguments not mandatory so, it must be passed by name.
The arguments parameter is an array, so regardless of what you name each element, I think it will still use it in order.
You can try doing something like this instead:
<s:RemoteObject destination="ColdFusion" source="cfc.categoryGateway" id="categoryGateway">
<s:method name="getCategoryList" result="returnHandler(event)"
fault="mx.controls.Alert.show(event.fault.faultString)" />
</s:RemoteObject>
then call:
categoryGateway.getCategoryList({orderby:'categoryId', parentCategory:'1'});
I have a Consumer class and a BillableConsumer : Consumer class. When trying to do any operation on my "Consumers" set, I get the error message "Object mapping could not be found for Type with identity Models.BillableConsumer.
From the CSDL:
<EntityType Name="BillableConsumer" BaseType="Models.Consumer">
<Property Type="String" Name="CardExpiratoin" Nullable="false" />
<Property Type="String" Name="CardNumber" Nullable="false" />
<Property Type="String" Name="City" Nullable="false" />
<Property Type="String" Name="Country" Nullable="false" />
<Property Type="String" Name="CVV" Nullable="false" />
<Property Type="String" Name="NameOnCard" Nullable="false" />
<Property Type="String" Name="PostalCode" Nullable="false" />
<Property Type="String" Name="State" />
<Property Type="String" Name="StreetAddress" Nullable="false" />
</EntityType>
From the C-S:
<EntitySetMapping Name="Consumers">
<EntityTypeMapping TypeName="IsTypeOf(Models.Consumer)">
<MappingFragment StoreEntitySet="consumer">
<ScalarProperty Name="LoginID" ColumnName="LoginID" />
<ScalarProperty Name="FirstName" ColumnName="FirstName" />
<ScalarProperty Name="LastName" ColumnName="LastName" />
</MappingFragment>
</EntityTypeMapping>
<EntityTypeMapping TypeName="IsTypeOf(Models.BillableConsumer)">
<MappingFragment StoreEntitySet="billinginformation">
<ScalarProperty Name="CardExpiratoin" ColumnName="CardExpiratoin" />
<ScalarProperty Name="CardNumber" ColumnName="CardNumber" />
<ScalarProperty Name="City" ColumnName="City" />
<ScalarProperty Name="Country" ColumnName="Country" />
<ScalarProperty Name="CVV" ColumnName="CVV" />
<ScalarProperty Name="LoginID" ColumnName="LoginID" />
<ScalarProperty Name="NameOnCard" ColumnName="NameOnCard" />
<ScalarProperty Name="PostalCode" ColumnName="PostalCode" />
<ScalarProperty Name="State" ColumnName="State" />
<ScalarProperty Name="StreetAddress" ColumnName="StreetAddress" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
Is this because I did not specifically add the BillableConsumer entity to the object set? How do I do that in a POCO scenario?
If you notice in my CSDL there is a column called "CardExpiratoin" (spelling mistake in DB column name). Of course my class which was hand-coded did not have this spelling mistake.
The way I found the problem is by generating POCOs from the T4 template, seeing it worked, and working my way back from there. Hope this helps anyone with the same problem. I also wish the error was a bit clearer to begin with.
I was experiencing this problem as well, and in my case it was also because of an error in a hand written POCO class. In most of the cases, you get an informational error messages, but as it seems in some rare cases you get something vague like 'Object mapping could not be found'.
In my particular case, there were columns of type VARCHAR(1) in the database, which I incorrectly mapped to char. I didn't try char?, but mapping to string certainly resolved the problem.