I have a Guidewire Gunit for a transformer in gosu which queries the system table to get a description for a result code which is working fine when run on the server but Gunit fails for the same.
I have tried the annotation #ServerTest for Gunit but that is failing as well.
The same code works fine in Gosu scratchpad.
PFA the code snippet as follows:
var resultCodes = Query.make(SystemTable).select().where(\elt -> elt.ResultCode == "AS01")
var description = ""
if(resultCodes != null && !resultCodes.isEmpty())
{
description = resultCodes.get(0).getFullDescription()
}
I'm getting the exception as follows :
java.lang.IllegalStateException: TableMetadataFactory cannot be used before it is started
Thanks,
Deepti
(Suggestion : )If your requirement is just to query based on some values.
Better dont use that .where() condition.
This is like SELECT * FROM <TABLE> and after getting all the data you are picking out your required result.
The best and the actual way is to use like
Query.make(TABLE_NAME).compare(TABLE_NAME#FIELD_NAME,Relop.Equals,"value_to_compare").select();
Query will be like
SELECT * FROM <TABLE_NAME> WHERE FIELD_NAME = FIELD_VALUE_TO_COMPARE;
While running Gunits, GW uses Shadow tables which will be basically empty.
Here if you are using OOTB entities, You can use Builder classes
or if you need to use some custom entities, use bundles to insert data first.
After inserting data into SystemTable (either using builder classes or bundles) run the below code.
var resultCodes = Query.make(SystemTable).compare(SystemTable#ResultCode ,Relop.Equals,"AS01").select()
foreach(result in resultCodes){
description = result.FullDescription
print("Output : "+description);
}
This happens when your RunLevel is set too low. Run levels below "NO_DAEMONS" will not load system tables. The default should be "NO_DAEMONS" so if you have an annotation on your test like this:
#RunLevel(gw.api.system.server.Runlevel.NONE)
either remove it or increase the level.
You can refactor your code like this:
uses gw.testharness.RunLevel
uses gw.api.database.Query
uses org.mockito.Mockito
uses gw.api.database.IQueryBeanResult
#RunLevel(NONE)
class StackOverflowTest {
function testDoQuery() {
var rs = Mockito.mock(IQueryBeanResult<SystemTable>)
var query = Mockito.mock(Query<SystemTable>)
Mockito.when(query.select()).thenReturn(rs)
var stackOverflow = Mockito.spy(new StackOverflow())
Mockito.doReturn(query).when(stackOverflow).getSystemTableQuery()
stackOverflow.doQuery()
Mockito.verify(stackOverflow, Mockito.times(1)).getSystemTableQuery()
Mockito.verify(query, Mockito.times(1)).select()
Mockito.verify(rs, Mockito.times(1)).iterator()
}
class StackOverflow {
function doQuery() {
var resultCodes = getSystemTableQuery().select().where(\elt -> elt.ResultCode == "AS01")
}
protected function getSystemTableQuery(): Query<SystemTable> {
return Query.make(SystemTable)
}
}
}
Related
From time to time I have the requirement to bind a control property to based on data out of model A to another model B.
For example the syntax could look like this (but will not work):
text : "{B>/rootB/{A>someValue}/propertyB}"
I normally solve this problem by "misusing" an unused control property in combination with the format function. It would look like this:
tooltip : {
path : "A>someValue",
formatter : function(oValue) {
// do some checks on oValue
var path = "B>/rootB/"+oValue+"/propertyB";
this.bindProperty("text", path);
return undefined; // because tooltip is not used
}
The benefit of this, each time "A>someValue" will be changed the binding of "text" will be updated automatically.
It is also possible to do this in template code (like items aggregations).
But you may smell the code ;)
Any suggestions to make it cleaner?
As far as I know, there is no such possibility in UI5 (yet). I always use a formatter function as you already mentioned. I say not YET, because developers seem to be aware of this feature request: see on GitHub
BUT, you dont need to missuse a random control property! Just use the formatter to read the needed values from any model you have access to:
text : {
path : "A>someValue1",
formatter : function(oValue) {
// read model B to get someValue2 (based on someValue1)
var path = "B>/rootB/"+oValue+"/propertyB";
var B = getModel("someModel");
var someValue2 = B.getProperty(path);
return someValue2
}
I receive the following error when I try to run my code. I haven't managed to solve it yet, please Help:
edit: Marked with * where it fails.
>
public IQueryable<Video> GetVideos([QueryString("id")] int? categorieId)
{
var _db = new TeleviziuneAcademicaAspSilverlight.Models.VideoContext();
IQueryable<Video> query = *_db.Videos;*
if (categorieId.HasValue && categorieId > 0)
{
query = query.Where(v => v.CategorieID == categorieId);
}
return query;
Change
IQueryable<Video> query =
to
IQueryable<Appname.Models.Video> query =
The reason for your error is that you have the type Video defined twice and because of using a short type name you accidentally reference not the one Video you should.
Also change it in the method's return value
public IQueryable<Appname.Models.Video> GetVideos( ... )
You seem to have two classes called Video. If you need both, you'll need to project from one to the other before your return statement:
return query.Select(dbVideo => new Appname.Video()
{
Prop1 = dbVideo.Prop1,
Prop2 = dbVideo.Prop2,
// etc.
});
Though you'll probably need to change the return type to an IEnumerable<> if you do that.
If you can just work with Appname.Models.Video, change IQueryable<Video> to IQueryable<Appname.Models.Video> in the method signature and the method body.
Let me explain you in details the scenario that I am having and the solution I am looking for.
Firstfully, I created a stored procedure that outputs simple things such as 2 tables and a message 'don't stop here'"
T-SQL:
USE [mydb]
GO
/****** Object: StoredProcedure [dbo].[BackupDatabase] Script Date: 2/26/2013 11:29:10 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
create PROCEDURE [dbo].[testing]
AS
BEGIN
select 'A' firstname, 'B' lastname;
print 'dont stop here'
select 1 final
END
Up until now I used to retriew the tables in a single manner by using datarowcollection class, and my static method looked like this:
C#:
public static class DataMan
{
public static DataRowCollection SelectData(string sql)
{
SqlDataSource DS = new SqlDataSource(CS, sql);
return ((DataView)DS.Select(DataSourceSelectArguments.Empty)).ToTable().Rows;
}
public static string CS = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
}
where I can easily get what i needed like here, and locate what evver row I wanted:
DataRowCollection people = Util.SelectData("Select * from students")
But now I am planning to create a stored procedure Like I mentioned above and do somthing like this, for instance:
**DataTableCollection** people = Util.SelectData("exec dbo.Testing")
UPDATE:
so I can locate the specific table from my storedprocedure.
I have tried to use DataTable, DataSet, DataTableCollections but no success.I can't use them in proper way.
Please help me
Thank You
Although it can be used in code-behind as you're illustrating here, the SqlDataSource is more typically used in a declarative manner on an ASP.NET markup page. However, given what you've started, when calling a stored procedure, you should set the SqlCommandType to StoredProcedure, supply the name of the procedure to SelectCommand, and return a DataReader. The DataReader, in turn, supports a NextResult() method that you can call to retrieve each discrete result set your procedure provides. Here is a framework of pseudo code that tries to illustrate how you might leverage this:
// pseudo code
void stub()
{
SqlDataSource d = new SqlDataSource(*connection string*);
d.DataSourceMode = SqlDataSourceMode.DataReader;
d.SelectCommandType = SqlDataSourceCommandType.StoredProcedure;
d.SelectCommand = "dbo.Testing";
// set some parameters
d.SelectParameters.Add("Parameter1Name","Parameter1Value"); // must be tailored to your proc!!
d.SelectParameters.Add("Parameter2Name","Parameter2Value"); // must be tailored to SqlDataReader r = (SqlDataReader) d.Select();
while (r.HasRows)
{
while (r.Read())
{
// do something with each row
}
// advance to next result set
r.NextResult();
}
r.Close();
}
We are rying to use WF with multiple tracking participants which essentially listen to different queries - one for activity states, one for custom tracknig records which are a subclass of CustomTrackingRecord.
The problem is that we can use both TrackingParticipants indivisually, but not together - we never get our subclass from CustomTrackingRecord but A CustomTrackingRecord.
If I put bopth queries into one TrackingParticipant and then handle everythign in one, both work perfectly (which indicates teh error is not where we throw them).
The code in question for the combined one is:
public WorkflowServiceTrackingParticipant ()
{
this.TrackingProfile = new TrackingProfile()
{
ActivityDefinitionId = "*",
ImplementationVisibility = ImplementationVisibility.All,
Name = "WorkflowServiceTrackingProfile",
Queries = {
new CustomTrackingQuery() { Name = "*", ActivityName = "*" },
new ActivityStateQuery() {
States = {
ActivityStates.Canceled,
ActivityStates.Closed,
ActivityStates.Executing,
ActivityStates.Faulted
}
},
}
};
}
When using two TrackingParticipants we have two TrackingProfile (with different names) that each have one of the queries.
in the track method, when using both separate, the lines:
protected override void Track(TrackingRecord record, TimeSpan timeout)
{
Console.WriteLine("*** ActivityTracking: " + record.GetType());
if (record is ActivityBasedTrackingRecord)
{
System.Diagnostics.Debugger.Break();
}
never result in the debugger hitting, when using only the one to track our CustomTrackingRecord subclass (ActivityBasedTrackingRecord) then it works.
Anyone else knows about this? For now we have combined both TrackingParticipants into one, but this has the bad side effect that we can not dynamically expand the logging possibilities, which we would love to. Is this a known issue with WWF somewhere?
Version used: 4.0 Sp1 Feature Update 1.
I guess I encounterad the exact same problem.
This problem occurs due to the restrictions of the extension mechanism. There can be only one instance per extension type per workflow instance (according to Microsoft's documentation). Interesting enough though, one can add multiple instances of the same type to one workflow's extensions which - in case of TrackingParticipant derivates - causes weird behavior, because only one of their tracking profiles is used for all participants of the respective type, but all their overrides of the Track method are getting invoked.
There is a (imho) ugly workaround to this: derive a new participant class from TrackingParticipant for each task (task1, task2, logging ...)
Regards,
Jacob
I think that this problem isn't caused by extension mechanism, since DerivedParticipant 1 and DerivedParticipant 2 are not the same type(WF internals just use polymorphism on the base class).
I was running on the same issue, my Derived1 was tracking records that weren't described in its profile.
Derived1.TrackingProfile.Name was "Foo" and Derived2.TrackingProfile.Name was null
I changed the name from null to "Bar" and it worked as expected.
Here is a WF internal reference code, describing how is the Profile selected
// System.Activities.Tracking.RuntimeTrackingProfile.RuntimeTrackingProfileCache
public RuntimeTrackingProfile GetRuntimeTrackingProfile(TrackingProfile profile, Activity rootElement)
{
RuntimeTrackingProfile runtimeTrackingProfile = null;
HybridCollection<RuntimeTrackingProfile> hybridCollection = null;
lock (this.cache)
{
if (!this.cache.TryGetValue(rootElement, out hybridCollection))
{
runtimeTrackingProfile = new RuntimeTrackingProfile(profile, rootElement);
hybridCollection = new HybridCollection<RuntimeTrackingProfile>();
hybridCollection.Add(runtimeTrackingProfile);
this.cache.Add(rootElement, hybridCollection);
}
else
{
ReadOnlyCollection<RuntimeTrackingProfile> readOnlyCollection = hybridCollection.AsReadOnly();
foreach (RuntimeTrackingProfile current in readOnlyCollection)
{
if (string.CompareOrdinal(profile.Name, current.associatedProfile.Name) == 0 && string.CompareOrdinal(profile.ActivityDefinitionId, current.associatedProfile.ActivityDefinitionId) == 0)
{
runtimeTrackingProfile = current;
break;
}
}
if (runtimeTrackingProfile == null)
{
runtimeTrackingProfile = new RuntimeTrackingProfile(profile, rootElement);
hybridCollection.Add(runtimeTrackingProfile);
}
}
}
return runtimeTrackingProfile;
}
I'm modifying the "Edit.aspx" default page template used by ASP.NET Dynamic Data and adding some additional controls. I know that I can find the type of object being edited by looking at DetailsDataSource.GetTable().EntityType, but how can I see the actual object itself? Also, can I change the properties of the object and tell the data context to submit those changes?
Maybe you have found a solution already, however I'd like to share my expresience on this.
It turned out to be a great pita, but I've managed to obtain the editing row. I had to extract the DetailsDataSource WhereParameters and then create a query in runtime.
The code below works for tables with a single primary key. If you have compound keys, I guess, it will require modifications:
Parameter param = null;
foreach(object item in (DetailsDataSource.WhereParameters[0] as DynamicQueryStringParameter).GetWhereParameters(DetailsDataSource)) {
param = (Parameter)item;
break;
}
IQueryable query = DetailsDataSource.GetTable().GetQuery();
ParameterExpression lambdaArgument = Expression.Parameter(query.ElementType, "");
object paramValue = Convert.ChangeType(param.DefaultValue, param.Type);
Expression compareExpr = Expression.Equal(
Expression.Property(lambdaArgument, param.Name),
Expression.Constant(paramValue)
);
Expression lambda = Expression.Lambda(compareExpr, lambdaArgument);
Expression filteredQuery = Expression.Call(typeof(Queryable), "Where", new Type[] { query.ElementType }, query.Expression, lambda);
var WANTED = query.Provider.CreateQuery(filteredQuery).Cast<object>().FirstOrDefault<object>();
If it's a DD object you may be able to use FieldTemplateUserControl.FindFieldTemplate(controlId). Then if you need to you can cast it as an ITextControl to manipulate data.
Otherwise, try using this extension method to find the child control:
public static T FindControl<T>(this Control startingControl, string id) where T : Control
{
T found = startingControl.FindControl(id) as T;
if (found == null)
{
found = FindChildControl<T>(startingControl, id);
}
return found;
}
I found another solution, the other ones did not work.
In my case, I've copied Edit.aspx in /CustomPages/Devices/
Where Devices is the name of the table for which I want this custom behaviour.
Add this in Edit.aspx -> Page_Init()
DetailsDataSource.Selected += entityDataSource_Selected;
Add this in Edit.aspx :
protected void entityDataSource_Selected(object sender, EntityDataSourceSelectedEventArgs e)
{
Device device = e.Results.Cast<Device>().First();
// you have the object/row being edited !
}
Just change Device to your own table name.