Source language: Translate to:

dbpSetFieldProperties

Questions about our Advanced Database plug-in

Moderator: Neosoft Support

dbpSetFieldProperties

Postby antonio45 » Fri Jul 20, 2007 5:51 am

Hi,

If you use dbpSetFieldProperties action, grid is working very slow, but if you don't use this action, grid is working fast.

Mehmet BAKITKAL
antonio45
 
Posts: 42
Joined: Fri Mar 31, 2006 11:37 am

Postby Neosoft Support » Fri Jul 20, 2007 10:04 am

I can't reproduce this here. What exactly is slow - scrolling? How large is your table? Where are you calling dbpSetFieldProperties? Can you provide a sample pub?
NeoSoft Support
Neosoft Support
NeoSoft Team
 
Posts: 5593
Joined: Thu Mar 31, 2005 10:48 pm
Location: Oregon, USA

dbpSetFieldProperties

Postby antonio45 » Sat Jul 21, 2007 12:53 pm

Hi,

My table's records count is 300. But the column count is 136. In my application, there is a Rectangle for the grid, there is a listbox which is showing tables's fields and field's orders. There is a Text entry for the autofind a record while a user writing in it, And There are two push buttons. One of them is for the connect and it's actions are like fallowing codes;

(Pushbutton1 (Connect button) )

dbpOpenDatabase "Northwind" "Provider=SQLOLEDB.1;Password=sa;Persist Security Info=True;User ID=sa;Initial Catalog=Northwind"
dbpOpenTable "NorthWind" "Customers" ""
dbpShowGrid "Northwind" "Customers" "Rectangle1"
dbpGetFieldNames "Northwind" "Customers" "[#13]" "[Fields]"
dbpSetGridProperties "Northwind" "Customers" "Color=Window;Font=ArialBlack,10,Normal,TURKISH_CHARSET;FontColor=WindowText;AlternateRowColor=Window;AlternateRowFontColor=WindowText;RowHeight=22;TitleColor=BtnFace;TitleFont=Tahoma,10,Normal,TURKISH_CHARSET;TitleFontColor=BtnText;TitleRowHeight=22;HighlightColor=Highlight;HighlightFontColor=HighlightText;EditColor=Window;EditFontColor=WindowText;ShowTitles=Yes;3DTitles=Yes;ShowGraphics=Yes;ShowIndicator=Yes;ShowColumnLines=Yes;ShowRowLines=Yes;GridLineWidth=1;GridLineColor=BtnFace;AllowRowResize=Yes;AllowColumnResize=Yes;AllowColumnSort=Yes;ConfirmDelete=Yes;ReadOnly=No;ShowNavigationBar=Yes;OnDoubleClick="

The other push button's actions are ;


(Pushbutton2 (for the Columns orders and fields properties))


ListBoxSize "ListBox1" "[TotalItems]"
SetVar "[Count]" "1"
SetVar "[ColumnOrder]" ""

WhileEx "[Count] < [TotalItems]"
ListBoxGetItem "ListBox1" "[Count]" "[GetItem]"
dbpSetFieldProperties "Northwind" "Customers" "[GetItem]" "Alignment=Left;TitleAlignment=Left;PickList=;DropDownRows=7;DisplayFormat=;EditMask=;ValidChars=;ColumnWidth=;ReadOnly=Yes;Visible=Yes"
SetVar "[ColumnOrder]" "[ColumnOrder][GetItem];"
dbpSetColumnOrder "Northwind" "Customers" "[ColumnOrder]" . Ordering the columns
SetVar "[Count]" "[Count] + 1"
EndWhile

And the text entry's textchange action is;

(TextEntry1)

StrLen "[SearchText]" "[TextLen]"
dbpShowErrors "Yes"
dbpQuery "NorthWind" "Customers" "ContactName LIKE '%[SearchText]%'"
dbpSetFieldProperties "Northwind" "Customers" "CustomerID" "Alignment=Left;TitleAlignment=Left;PickList=;DropDownRows=7;DisplayFormat=;EditMask=;ValidChars=;ColumnWidth=;ReadOnly=No;Visible=No"
dbpSetFieldProperties "Northwind" "Customers" "Region" "Alignment=Left;TitleAlignment=Left;PickList=;DropDownRows=7;DisplayFormat=;EditMask=;ValidChars=;ColumnWidth=;ReadOnly=No;Visible=No"
dbpSetFieldProperties "Northwind" "Customers" "PostalCode" "Alignment=Left;TitleAlignment=Left;PickList=;DropDownRows=7;DisplayFormat=;EditMask=;ValidChars=;ColumnWidth=;ReadOnly=No;Visible=No"
dbpSetFieldProperties "Northwind" "Customers" "Phone" "Alignment=Left;TitleAlignment=Left;PickList=;DropDownRows=7;DisplayFormat=;EditMask=;ValidChars=;ColumnWidth=;ReadOnly=No;Visible=No"


If you don't push the pushbutton2, the grid is finding record fast while the user writing in textentry cell. But if you push the pushbutton2, the gris is very slow for the 300 records and 136 columns.


I hope you understand because of my bad English.

Thank you for your help

Mehmet BAKITKAL
antonio45
 
Posts: 42
Joined: Fri Mar 31, 2006 11:37 am

Postby Neosoft Support » Mon Jul 23, 2007 10:03 pm

Isn't the Northwind database an MS Access example rather than an SQL server example?

dbpOpenDatabase "NorthWind" "[PubDir]Nwind.mdb"
NeoSoft Support
Neosoft Support
NeoSoft Team
 
Posts: 5593
Joined: Thu Mar 31, 2005 10:48 pm
Location: Oregon, USA

dbpSetFieldProperties

Postby antonio45 » Mon Jul 23, 2007 11:02 pm

Yes it is MSSQL example. But it was only a sample. You can change it to a diffirent database, and I am sure you will get samething.

I don't know if dbpSetFieldProperties action or dbpSetColumnOrder action effects to slow grid down.

Mehmet BAKITKAL
antonio45
 
Posts: 42
Joined: Fri Mar 31, 2006 11:37 am

Postby Wrangler » Tue Jul 24, 2007 8:46 am

Try setting the grid properties before you show the grid.
Wrangler
--------------
"You never know about a woman. Whether she'll laugh, cry or go for a gun." - Louis L'Amour

Windows 7 Ultimate SP1 64bit
16GB Ram
Asus GTX 950 OC Strix
Software made with NeoBook
http://highdesertsoftware.com
User avatar
Wrangler
 
Posts: 1505
Joined: Thu Mar 31, 2005 11:40 pm
Location: USA

Postby Gaev » Tue Jul 24, 2007 9:37 am

Mehmet BAKITKAL:

Just looking at your code ...

a) do you have any way of confirming that the WhileEx/EndWhile processing is completed before you start entering text in the Search Box ?

b) you might want to place the command dbpSetColumnOrder "Northwind" "Customers" "[ColumnOrder]" outside the WhileEx/EndWhile block of code ... with 136 fields (columns) in your database, you are invoking this command 136 times ... first with just one field/column name, then with two, then with three etc.

c) also (for testing purposes), place an AlertBox command at the end of the code for PushButton2 ... just to confirm that all code has been serviced before you begin with the Search.


As for the code related to the Search ... note that the code in the TextChange section has to be executed ... and completed in the time it takes you to type the next character on your keyboard ... the dbpQuery command itself migh exceed this time window when using sizable databases ... as for the rest of the commands ...

a) You probably can avoid the dbpShowErrors inside this section ... so it does not have to be serviced with each keystroke.

b) Don't know if there are just 4 dbpSetFieldProperties commands ... as in your post above ... or 136 of them ... in any case try ...

i) commenting them out temporarily and see if it improves performance
ii) service them outside of the TextChange section and see if it helps
User avatar
Gaev
 
Posts: 3716
Joined: Fri Apr 01, 2005 7:48 am
Location: Toronto, Canada

Postby Neosoft Support » Tue Jul 24, 2007 8:53 pm

Good catch Gaev! Yes, executing all that code after every single keystroke might be too much. Also, the TextEntry1 code may be executing whenever you navigate the table if the object is associated with a database variable. That would definitely slow things down.
NeoSoft Support
Neosoft Support
NeoSoft Team
 
Posts: 5593
Joined: Thu Mar 31, 2005 10:48 pm
Location: Oregon, USA

dbpSetFieldProperties

Postby antonio45 » Wed Jul 25, 2007 12:53 am

Hi Gaev,

Thank you for your explenations. But I used a sample database in example. Normally, the program don't know which database is being used. Because There are a lot of databases at the listbox and When the user selects one, the program is opening it and showing it in a grid. I want to answer your questions now

a) do you have any way of confirming that the WhileEx/EndWhile processing is completed before you start entering text in the Search Box ?

Yes I put a AlertBox out side of WhileEx/EndWhile processing and it is being shown once. This is true, because I pushed the push button once not more.

b) you might want to place the command dbpSetColumnOrder "Northwind" "Customers" "[ColumnOrder]" outside the WhileEx/EndWhile block of code ... with 136 fields (columns) in your database, you are invoking this command 136 times ... first with just one field/column name, then with two, then with three etc.

You are true and I cancelled this action. (dbpSetColumnOrder )


c) also (for testing purposes), place an AlertBox command at the end of the code for PushButton2 ... just to confirm that all code has been serviced before you begin with the Search.

I put a AlertBox and I confirm that all code has been serviced before I begin with the search.


As for the code related to the Search ... note that the code in the TextChange section has to be executed ... and completed in the time it takes you to type the next character on your keyboard ... the dbpQuery command itself migh exceed this time window when using sizable databases ... as for the rest of the commands ...

a) You probably can avoid the dbpShowErrors inside this section ... so it does not have to be serviced with each keystroke

I put dbfShowErrors in this section but there isn't any error occured.

b) Don't know if there are just 4 dbpSetFieldProperties commands ... as in your post above ... or 136 of them ... in any case try ...

It was only a sample. I tried it at the another table which has 136 colums and nearly 300 records. I tried diffirent tables but the same slow down problem is occured.

i) commenting them out temporarily and see if it improves performance

If I don't push the pushbutton2, and when I write a text in a text entry box, the search processing is very quick. But if I push the pushbutton2 once and when I write a text in a text enry box, the search processing is very slow.Grid scrolling is also slow.

ii) service them outside of the TextChange section and see if it helps
Why ?. Becouse if I don't push the push button2, It is working normaly. And I want to find a text while I write a character.

May be I must tell you that program logic.


1- User is selecting Database first.
2- The program listing tables of Database in the listbox at the left side.
3- When the user select a table in listbox, the program showing the records in a grid at the right side.
4- There is a TextEntryBox at bottom and There is a ComboBox. When the user select a Table, I am filling fields of table at the ComboBox. So the User selecting a search field.
5- When the user writing a text in the textentry box, the program is searching text in the search field.

This is working normaly in my application.
But,

6- There is a Pushbutton at the Right side. When the user pushed it., a windows is opening. There are two listbox in this window. At the left side, fields of table is being shown. These fields are visible at the table. But If the user don't want them visible, he is selecting them from left listbox to right listbox. And When the user closed this window, program is checking which fields will be visible and which is invisible. So the pushbutton action is working.

IF I don't push this button, everything is ok.

May be You can try at a little sample. Or I can send you my application.

My codes in Pushbutton2 are ;

If "[ActiveTable]" "<>" ""
CustomWindow "Select a Field as a Visible or invisible" "191" "224" "Container6" "ToolWindow+Exclusive"

ListBoxSize "ListBox3" "[SizeVisible]"

ListBoxSize "ListBox4" "[SizeInvisible]"


SetVar "[Count]" "1"
. SetVar "[ColumnsOrder]" ""

WhileEx "[Saybak] <= [SizeVisible]"
ListBoxGetItem "ListBox3" "[Count]" "[GetList]"
.AlertBox "" "[Getlist]"
dbpSetFieldProperties "[DatabaseName]" "[ActiveTable]" "[GetList]" "ReadOnly=Yes;Visible=Yes"
SetVar "[ColumnsOrder]" "[ColumnsOrder][Getlist];"
SetVar "[Count]" "[Count] + 1"
EndWhile


. If "[ColumnsOrder]" "=" ""

. Else
.dbpSetColumnOrder "[DatabaseName]" "[ActiveTable]" "[ColumnsOrder]"
. EndIf




SetVar "[Count]" "1"
WhileEx "[Count] <= [SizeInvisible]"
ListBoxGetItem "ListBox4" "[Count]" "[GetList]"
dbpSetFieldProperties "[DatabaseName]" "[ActiveTable]" "[GetList]" "ReadOnly=Yes;Visible=No"
SetVar "[Count]" "[Count] + 1"
EndWhile
Else
AlertBox "Uyarı" "PLEASE SELECT TABLE FIRST"
Endif
dbpShowGrid "[DatabaseName]" "[ActiveTable]" "Rectangle1"





Thank You for your Help again

Mehmet BAKITKAL
antonio45
 
Posts: 42
Joined: Fri Mar 31, 2006 11:37 am

Postby Gaev » Wed Jul 25, 2007 6:56 am

Mehmet BAKITKAL:

1) So we have confirmed that the actions for Push Button 2 are completed before you click on the Search button.

2) From all your descriptions, it appears that when you explicitly define Column Orders, the processing of dbpQuery and (multiple) dbpSetFieldProperties (in a loop) are not serviced faster than the time it takes to type a keystroke ... but (according to you) ... not a problem if the Column Orders (and visibility properties) are not specified for each of the columns.

3) SInce you did not answer all my questions in the previous post ... try this ...
Code: Select all
.... Pushbutton2

If "[ActiveTable]" "<>" ""
   CustomWindow "Select a Field as a Visible or invisible" "191" "224" "Container6" "ToolWindow+Exclusive"
   ListBoxSize "ListBox3" "[SizeVisible]"
   ListBoxSize "ListBox4" "[SizeInvisible]"
   SetVar "[Count]" "1"
   SetVar "[ColumnsOrder]" ""

   WhileEx "[Saybak] <= [SizeVisible]"
      ListBoxGetItem "ListBox3" "[Count]" "[GetList]"
      AlertBox "" "[Getlist]"
      dbpSetFieldProperties "[DatabaseName]" "[ActiveTable]" "[GetList]" "ReadOnly=Yes;Visible=Yes"
      SetVar "[ColumnsOrder]" "[ColumnsOrder][Getlist];"
      SetVar "[Count]" "[Count] + 1"
   EndWhile
   AlertBox "Done" "Visible=yes"

   If "[ColumnsOrder]" "=" ""
   Else
      dbpSetColumnOrder "[DatabaseName]" "[ActiveTable]" "[ColumnsOrder]"
   EndIf

   SetVar "[Count]" "1"
   WhileEx "[Count] <= [SizeInvisible]"
      ListBoxGetItem "ListBox4" "[Count]" "[GetList]"
      dbpSetFieldProperties "[DatabaseName]" "[ActiveTable]" "[GetList]" "ReadOnly=Yes;Visible=No"
      SetVar "[Count]" "[Count] + 1"
   EndWhile
   AlertBox "Done" "Visible=no"

   dbpShowGrid "[DatabaseName]" "[ActiveTable]" "Rectangle1"

   SetVar "[FirstSearchTime]" "Yes"
Else
   AlertBox "Uyarı" "PLEASE SELECT TABLE FIRST"
Endif

... and ...
Code: Select all
... TextEntry1
StrLen "[SearchText]" "[TextLen]"
dbpQuery "NorthWind" "Customers" "ContactName LIKE '%[SearchText]%'"
If "[FirstSearchTime]" "=" "Yes"
   dbpShowErrors "Yes"
   dbpSetFieldProperties "Northwind" "Customers" "CustomerID" "Alignment=Left;TitleAlignment=Left;PickList=;DropDownRows=7;DisplayFormat=;EditMask=;ValidChars=;ColumnWidth=;ReadOnly=No;Visible=No"
   dbpSetFieldProperties "Northwind" "Customers" "Region" "Alignment=Left;TitleAlignment=Left;PickList=;DropDownRows=7;DisplayFormat=;EditMask=;ValidChars=;ColumnWidth=;ReadOnly=No;Visible=No"
   dbpSetFieldProperties "Northwind" "Customers" "PostalCode" "Alignment=Left;TitleAlignment=Left;PickList=;DropDownRows=7;DisplayFormat=;EditMask=;ValidChars=;ColumnWidth=;ReadOnly=No;Visible=No"
   dbpSetFieldProperties "Northwind" "Customers" "Phone" "Alignment=Left;TitleAlignment=Left;PickList=;DropDownRows=7;DisplayFormat=;EditMask=;ValidChars=;ColumnWidth=;ReadOnly=No;Visible=No"
   SetVar "[FirstSearchTime]" "No"
EndIf
AlertBox "Done" "dbpQuery"


Now observe the time it takes for each step of the process ... in particular, see if the second and subsequent letters you type in the Search Box respond faster than the first ...

(a) if they do, you can consider moving the code associated with the condition [FirstSearchTime]=Yes to the end of the processing for Push Button 2 ... so you get a fast response even after the first keystroke.

(b) if they don't, it is the subsequent dbpSetFileProperties ... in combination with explicit definitions of properties for each column ... that is slowing things down ... in which case you might have to consider one of two different approaches ...

i) place a button next to the Search Box ... and only do the query when user clicks on this button

ii) if (i) takes away the "eye candy" of seeing selections change with every keystroke ... you might consider rewamping your design of Push Button 2 ... instead of marking each column as Visible/Invisible ... create a temporary database copy with just the "visible" columns ... and do subsequent searches on this copied database instead of the originals.


In your response, perhaps you can detail the database columns, rows, visible columns you are testing with ... as well as the approximate times it takes between each of the actions/AlertBox responses.
User avatar
Gaev
 
Posts: 3716
Joined: Fri Apr 01, 2005 7:48 am
Location: Toronto, Canada

Postby Gaev » Wed Jul 25, 2007 7:04 am

BTW, in your post of July/21 3:53 p.m., if you break up that one long line like so ...

"Color=Window;Font=ArialBlack,10,Normal,TURKISH_CHARSET;
FontColor=WindowText;AlternateRowColor=Window;
AlternateRowFontColor=WindowText;RowHeight=22;TitleColor=BtnFace;
TitleFont=Tahoma,10,Normal,TURKISH_CHARSET;
TitleFontColor=BtnText;TitleRowHeight=22;HighlightColor=Highlight;
HighlightFontColor=HighlightText;EditColor=Window;
EditFontColor=WindowText;ShowTitles=Yes;3DTitles=Yes;
ShowGraphics=Yes;ShowIndicator=Yes;ShowColumnLines=Yes;
ShowRowLines=Yes;GridLineWidth=1;GridLineColor=BtnFace;
AllowRowResize=Yes;AllowColumnResize=Yes;AllowColumnSort=Yes;
ConfirmDelete=Yes;ReadOnly=No;ShowNavigationBar=Yes;
OnDoubleClick="

... it will make all the other posts easier to read (without repeated horizontal scrolling).
User avatar
Gaev
 
Posts: 3716
Joined: Fri Apr 01, 2005 7:48 am
Location: Toronto, Canada

dbpSetFieldProperties

Postby antonio45 » Wed Jul 25, 2007 7:33 am

Hi Gaev,

Thank you for your reply.

I tried your codes in my application. And If I don't push the Pushbutton2

This code is working and the grid is very fast.

StrLen "[SearchText]" "[TextLen]"
dbpQuery "NorthWind" "Customers" "ContactName LIKE '%[SearchText]%'"
If "[FirstSearchTime]" "=" "Yes"
dbpShowErrors "Yes"
dbpSetFieldProperties "Northwind" "Customers" "CustomerID" "Alignment=Left;TitleAlignment=Left;PickList=;DropDownRows=7;DisplayFormat=;EditMask=;ValidChars=;ColumnWidth=;ReadOnly=No;Visible=No"
dbpSetFieldProperties "Northwind" "Customers" "Region" "Alignment=Left;TitleAlignment=Left;PickList=;DropDownRows=7;DisplayFormat=;EditMask=;ValidChars=;ColumnWidth=;ReadOnly=No;Visible=No"
dbpSetFieldProperties "Northwind" "Customers" "PostalCode" "Alignment=Left;TitleAlignment=Left;PickList=;DropDownRows=7;DisplayFormat=;EditMask=;ValidChars=;ColumnWidth=;ReadOnly=No;Visible=No"
dbpSetFieldProperties "Northwind" "Customers" "Phone" "Alignment=Left;TitleAlignment=Left;PickList=;DropDownRows=7;DisplayFormat=;EditMask=;ValidChars=;ColumnWidth=;ReadOnly=No;Visible=No"
SetVar "[FirstSearchTime]" "No"
EndIf
AlertBox "Done" "dbpQuery"


But if I pushed the pushbutton2


Fallowing code is working


If "[ActiveTable]" "<>" ""
CustomWindow "Select a Field as a Visible or invisible" "191" "224" "Container6" "ToolWindow+Exclusive"
ListBoxSize "ListBox3" "[SizeVisible]"
ListBoxSize "ListBox4" "[SizeInvisible]"
SetVar "[Count]" "1"
SetVar "[ColumnsOrder]" ""

WhileEx "[Saybak] <= [SizeVisible]"
ListBoxGetItem "ListBox3" "[Count]" "[GetList]"
AlertBox "" "[Getlist]"
dbpSetFieldProperties "[DatabaseName]" "[ActiveTable]" "[GetList]" "ReadOnly=Yes;Visible=Yes"
SetVar "[ColumnsOrder]" "[ColumnsOrder][Getlist];"
SetVar "[Count]" "[Count] + 1"
EndWhile
AlertBox "Done" "Visible=yes"

If "[ColumnsOrder]" "=" ""
Else
dbpSetColumnOrder "[DatabaseName]" "[ActiveTable]" "[ColumnsOrder]"
EndIf

SetVar "[Count]" "1"
WhileEx "[Count] <= [SizeInvisible]"
ListBoxGetItem "ListBox4" "[Count]" "[GetList]"
dbpSetFieldProperties "[DatabaseName]" "[ActiveTable]" "[GetList]" "ReadOnly=Yes;Visible=No"
SetVar "[Count]" "[Count] + 1"
EndWhile
AlertBox "Done" "Visible=no"

dbpShowGrid "[DatabaseName]" "[ActiveTable]" "Rectangle1"

SetVar "[FirstSearchTime]" "Yes"
Else
AlertBox "Uyarı" "PLEASE SELECT TABLE FIRST"
Endif

and grid is working very slow.


I tred to write textentry a lot of things without not push the pushbutton2, the grid was very fast.

Mehmet BAKITKAL
antonio45
 
Posts: 42
Joined: Fri Mar 31, 2006 11:37 am

Postby Gaev » Wed Jul 25, 2007 8:44 am

Mehmet BAKITKAL:

a) You will have to consider one of two different approaches ...

i) place a button next to the Search Box ... and only do the query when user clicks on this button

ii) if (i) takes away the "eye candy" of seeing selections change with every keystroke ... you might consider rewamping your design of Push Button 2 ... instead of marking each column as Visible/Invisible ... create a temporary database copy with just the "visible" columns ... and do subsequent searches on this copied database instead of the originals.


b) you didn't mention the actual response times (a second or two ? , tens of seconds ?) ... so I am not sure if even (i) is going to be satisfactory.
User avatar
Gaev
 
Posts: 3716
Joined: Fri Apr 01, 2005 7:48 am
Location: Toronto, Canada

dbpSetFieldProperties

Postby antonio45 » Wed Jul 25, 2007 9:19 am

Hi Gaev,

I put a new pushbutton, and it's Action is only
dbpQuery "NorthWind" "Customers" "ContactName LIKE '%[SearchText]%'"


1. If I don't push pushbutton2 and I push this new pushbutton, the grid is showing these records half and 1 second.

2- If I pushed the pushbutton2 once and after I pushed this new button, the grid is showing these records 7 seconds later. (After I pushed pushbutton2, I pushed this button 1 minutes later. Because may be it can process something in memory)

Mehmet BAKITKAL
antonio45
 
Posts: 42
Joined: Fri Mar 31, 2006 11:37 am

Postby Gaev » Wed Jul 25, 2007 9:45 am

Mehmet BAKITKAL:

Looks like ...

a) when the display/format is the "default", the query takes half to one second ... still too slow to be completed between keystrokes for a normal data entry user ... so I would definitely not consider doing it between keystrokes ... just have the user click on the adjacent button after typing the full search word/phrase.

b) when the display/format is "customized", the query takes seven seconds ... looks like "formating" every column/field in every "row resulting from the query" takes a long time ... you have to make a decision ... either not offer the capability to make columns invisible ... or just make a temporary copy of the database with just the visible columns in it ... and then display rows from this copied database.
User avatar
Gaev
 
Posts: 3716
Joined: Fri Apr 01, 2005 7:48 am
Location: Toronto, Canada

Next

Return to NeoBookDBPro

Who is online

Users browsing this forum: Yahoo [Bot] and 1 guest