问:
How to combine one to one entity with many to many
Hallo I have a situation that I have a problem with:

I Have 3 models lets say Device, Inbox and Suffix.
Device can have only one Inbox and Inbox can be assign to many devices
And Inbox and Suffix are connected with many to many relationship by junction table.

fluent api for inbox(SectionName) and sugffix would look like:

```<code>            modelBuilder.Entity<SectionName>()
            .HasMany(suffix => suffix.SectionsSuffix)
            .WithMany(name => name.SectionsName)
            .Map(nameSuffix =>
            {
                nameSuffix.ToTable("SectionsNameSuffix");
                nameSuffix.MapLeftKey("SectionNameId");
                nameSuffix.MapRightKey("SectionSuffixId");
            });
</code>```

Models are nothing special:

Inbox:

```<code>[Table("SectionsName")]
public class SectionName : BaseEntity
{
    public SectionName()
    {
        SectionsSuffix = new List<SectionSuffix>();
    }

    [Required]
    public string Name { get; set; }

    public ICollection<SectionSuffix> SectionsSuffix { get; set; }
}
</code>```

Suffix:

```<code>[Table("SectionsSuffix")]
public class SectionSuffix : BaseEntity
{
    public SectionSuffix()
    {
        SectionLines = new List<SectionLine>();
        SectionsName = new List<SectionName>();
    }

    [Required]
    public string Name { get; set; }

    public ICollection<SectionLine> SectionLines { get; set; }
    public ICollection<SectionName> SectionsName { get; set; }
}
</code>```

And device:

```<code>public class Device
{
    protected Device()
    {
    }

    public int Id { get; set; }

    public string Description { get; set; }

    public int? InboxId { get; set; }

    [ForeignKey("InboxId")]
    public virtual SectionName Inbox { get; set; }
}
</code>```

So basically one device can be connected to single combination of inbox and suffix

Suffix is connected to another many to many but that's just for information.

Now, I am looking for a way to when I get records from device entity will know witch combination is used. I was thinking about adding additional column to junction table, but would that complicate things, and I wonder if there is a another way to do it.

答: Putting id combination in main table did the trick.</p>

Body:
Hallo I have a situation that I have a problem with:

I Have 3 models lets say Device, Inbox and Suffix.
Device can have only one Inbox and Inbox can be assign to many devices
And Inbox and Suffix are connected with many to many relationship by junction table.

fluent api for inbox(SectionName) and sugffix would look like:

            modelBuilder.Entity<SectionName>()
            .HasMany(suffix => suffix.SectionsSuffix)
            .WithMany(name => name.SectionsName)
            .Map(nameSuffix =>
            {
                nameSuffix.ToTable("SectionsNameSuffix");
                nameSuffix.MapLeftKey("SectionNameId");
                nameSuffix.MapRightKey("SectionSuffixId");
            });

Models are nothing special:

Inbox:

[Table("SectionsName")]
public class SectionName : BaseEntity
{
    public SectionName()
    {
        SectionsSuffix = new List<SectionSuffix>();
    }

    [Required]
    public string Name { get; set; }

    public ICollection<SectionSuffix> SectionsSuffix { get; set; }
}

Suffix:

[Table("SectionsSuffix")]
public class SectionSuffix : BaseEntity
{
    public SectionSuffix()
    {
        SectionLines = new List<SectionLine>();
        SectionsName = new List<SectionName>();
    }

    [Required]
    public string Name { get; set; }

    public ICollection<SectionLine> SectionLines { get; set; }
    public ICollection<SectionName> SectionsName { get; set; }
}

And device:

public class Device
{
    protected Device()
    {
    }

    public int Id { get; set; }

    public string Description { get; set; }

    public int? InboxId { get; set; }

    [ForeignKey("InboxId")]
    public virtual SectionName Inbox { get; set; }
}

So basically one device can be connected to single combination of inbox and suffix

Suffix is connected to another many to many but that's just for information.

Now, I am looking for a way to when I get records from device entity will know witch combination is used. I was thinking about adding additional column to junction table, but would that complicate things, and I wonder if there is a another way to do it.


来源: stackexchange

问:
How is downcasting/upcasting done between 2 interfaces in Selenium WebDriver in Java in Excel
Interface WritableSheet  extends  interface Sheet (jxl) library.   I want to use the addCell() that is there in
WritableSheet.

But when I try to convert Sheet object to WritableSheet object,I get ClassCastException. I want to know how to typecast between two interfaces.

Below is my code :

```<code>package xyz;
import java.io.File;
import java.io.IOException;
import jxl.Cell;
import jxl.Sheet;
import jxl.Workbook;
import jxl.read.biff.BiffException;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WriteException;
import jxl.write.biff.RowsExceededException;
public class WriteExcel12
{
   public static Workbook wb;
   public static Sheet s;
   public static Cell c;
   public static WritableSheet ws;
   public static Label l;
   public static void main(String[] args) throws BiffException, IOException, RowsExceededException, WriteException
    {
        File f=new File("D:/Input.xls");
        wb=Workbook.getWorkbook(f);
        s=wb.getSheet("Data");

        //WritableSheet extends Sheet
        ws=(WritableSheet)s;//ClassCastException here

        //Read cell(0,0) from Sheet named Data
        c=s.getCell(0,0);
        String a=c.getContents();

        //Read cell(0,1) from Sheet named Data
        c=s.getCell(1,0);
        String b=c.getContents();

        //Read cell(0,2) from Sheet named Data
        c=s.getCell(2,0);
        String d=c.getContents();

        //Convert String to integer
        int e=Integer.parseInt(a);
        System.out.println(e);

        int g=Integer.parseInt(b);
        System.out.println(g);

        int h=Integer.parseInt(d);
        System.out.println(h);

        //Perform addition
        int result=e+g+h;
        System.out.println(result);

        //Convert result which is it to String
        String ans=Integer.toString(result);

        // Write String  ans to cell(0,3)
        l=new Label(3,0,ans);
        ws.addCell(l);
    }
}
</code>```

Data.xls

10| 20| 30|

答:
You can create a WritableWorkbook from your Workbook.Then you can get your WritableSheet .

```<code>File f=new File("D:/Input.xls");
wb=Workbook.getWorkbook(f);
WritableWorkbook copy = Workbook.createWorkbook(f, workbook);
WritableSheet sheet = copy.getSheet("Data");
</code>```

ContentLicense: CC BY-SA 3.0

Body:
Interface WritableSheet  extends  interface Sheet (jxl) library.   I want to use the addCell() that is there in
WritableSheet.

But when I try to convert Sheet object to WritableSheet object,I get ClassCastException. I want to know how to typecast between two interfaces.

Below is my code :

package xyz;
import java.io.File;
import java.io.IOException;
import jxl.Cell;
import jxl.Sheet;
import jxl.Workbook;
import jxl.read.biff.BiffException;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WriteException;
import jxl.write.biff.RowsExceededException;
public class WriteExcel12
{
   public static Workbook wb;
   public static Sheet s;
   public static Cell c;
   public static WritableSheet ws;
   public static Label l;
   public static void main(String[] args) throws BiffException, IOException, RowsExceededException, WriteException
    {
        File f=new File("D:/Input.xls");
        wb=Workbook.getWorkbook(f);
        s=wb.getSheet("Data");

        //WritableSheet extends Sheet
        ws=(WritableSheet)s;//ClassCastException here

        //Read cell(0,0) from Sheet named Data
        c=s.getCell(0,0);
        String a=c.getContents();

        //Read cell(0,1) from Sheet named Data
        c=s.getCell(1,0);
        String b=c.getContents();

        //Read cell(0,2) from Sheet named Data
        c=s.getCell(2,0);
        String d=c.getContents();

        //Convert String to integer
        int e=Integer.parseInt(a);
        System.out.println(e);

        int g=Integer.parseInt(b);
        System.out.println(g);

        int h=Integer.parseInt(d);
        System.out.println(h);

        //Perform addition
        int result=e+g+h;
        System.out.println(result);

        //Convert result which is it to String
        String ans=Integer.toString(result);

        // Write String  ans to cell(0,3)
        l=new Label(3,0,ans);
        ws.addCell(l);
    }
}

Data.xls

10| 20| 30|

Body:
You can create a WritableWorkbook from your Workbook.Then you can get your WritableSheet .

File f=new File("D:/Input.xls");
wb=Workbook.getWorkbook(f);
WritableWorkbook copy = Workbook.createWorkbook(f, workbook);
WritableSheet sheet = copy.getSheet("Data");


问:
Running two subscription methods in one in order to get results in Angular 5
My app contains two components. One gets items from the API and lists them. When an item is clicked, it passes detailed information to the second component that uses a PrimeNg datatable, which then displays it. Because the second component is dependent on the first based on the item selected, how can I send that data to the second component once an item has been clicked?

Currently, I'm using a BehaviorSubject to relay the item details to the second component. The problem is, is that I want to modify or delete some of the items and as far as I know, you can't delete objects from a BehaviourSubject subscription. My thinking is that I should not use a BehaviourSubject and somehow get the item id and in the same method use that id to get the item details?

My service file:

```<code>source: Source;
public sourceUpdate = new BehaviorSubject<Source>(this.source);
currentSource = this.sourceUpdate.asObservable();

//BehaviourSubject method
changeSources(sources) {
        this.sourceSUpdate.next(sources);
        console.log(sources);
    }

//Get items
getSources(): Observable<Source[]> {
        let cpHeaders = new Headers({ 'Content-Type': 'application/json' });
        let queryString = '[{"Name": "deleted","Values": ["false"]}';
        let options = new RequestOptions({ headers: cpHeaders});
      return this.http.post('api/V1/Source/QueryDocument', queryString, options)
        .map(data =>  {return this.extractData(data);})
        .catch(this.handleError);
    }
//Get item details by item id
    getStatementsBySource(sourceId?: string): Observable<Statement[]> {
            let cpHeaders = new Headers({ 'Content-Type': 'application/json' });
            // let cpParams = new URLSearchParams();
            let queryString = '[{"Name": "source.sourceId","Values": ["' + sourceId + '"]},{"Name": "deleted", "Values": ["false"]}]';
            console.log(sourceId);
            let options = new RequestOptions({ headers: cpHeaders});
          return this.http.post('api/V1/Statement/QueryDocument', queryString, options)
            .map(data =>  {return this.extractData(data);},(statements => {
                  return statements.map(statement => new Statement(statement));}))
            .catch(this.handleError);
        }

private extractData(res: Response) {
        let body = res.json();
        console.log(body);
        return body;
    }

    private handleError (error: Response | any) {
        console.error(error.message || error);
        console.log("error");
        return Observable.throw(error.status);
    }
</code>```

First component:

```<code>getSources() {
      this.sourceDisplayService.getSources().subscribe(sources => {this.sources = sources;});
    }
onRowSelect(event) {
this.sourceDisplayService.changeSource(this.source);
}
</code>```

Second component:

```<code> this.subscription = this.sourceDisplayService.currentSource.subscribe(source => this.source = source);
</code>```

答:
At first, I suggest you to store the full api result in your behaviorSubject:

```<code>private _sources = new BehaviorSubject<Source[]>([]);
public sources = this._sources.asObservable();

initData() {
  ...
  this.http.post('api/V1/Statement/QueryDocument', queryString, options)
  .subscribe(result => { this._sources.next(result); }
}
</code>```

Now, to avoid a double subscription, you can bind the content of clicked source as input on the second component.
The implementation depends of the hierarchy of your components: is the second component child of the first, or they are both at the same level?

In case of same level components: Bind click event on the first to store the source row in a parent variable. Then bind the parent source variable to the second component:

<component-1 (click)="currSource=source" *ngFor="let source of service.sources | async"></component-1>

<component-2 [source]="currSource"></component-2>

In case of component 2 child of component 1:
do the same but store the row source in the component 1 and bind it directly to the child component.

You can now display the content of source without subscribe to an other subject.

Body:
My app contains two components. One gets items from the API and lists them. When an item is clicked, it passes detailed information to the second component that uses a PrimeNg datatable, which then displays it. Because the second component is dependent on the first based on the item selected, how can I send that data to the second component once an item has been clicked?

Currently, I'm using a BehaviorSubject to relay the item details to the second component. The problem is, is that I want to modify or delete some of the items and as far as I know, you can't delete objects from a BehaviourSubject subscription. My thinking is that I should not use a BehaviourSubject and somehow get the item id and in the same method use that id to get the item details?

My service file:

source: Source;
public sourceUpdate = new BehaviorSubject<Source>(this.source);
currentSource = this.sourceUpdate.asObservable();

//BehaviourSubject method
changeSources(sources) {
        this.sourceSUpdate.next(sources);
        console.log(sources);
    }

//Get items
getSources(): Observable<Source[]> {
        let cpHeaders = new Headers({ 'Content-Type': 'application/json' });
        let queryString = '[{"Name": "deleted","Values": ["false"]}';
        let options = new RequestOptions({ headers: cpHeaders});
      return this.http.post('api/V1/Source/QueryDocument', queryString, options)
        .map(data =>  {return this.extractData(data);})
        .catch(this.handleError);
    }
//Get item details by item id
    getStatementsBySource(sourceId?: string): Observable<Statement[]> {
            let cpHeaders = new Headers({ 'Content-Type': 'application/json' });
            // let cpParams = new URLSearchParams();
            let queryString = '[{"Name": "source.sourceId","Values": ["' + sourceId + '"]},{"Name": "deleted", "Values": ["false"]}]';
            console.log(sourceId);
            let options = new RequestOptions({ headers: cpHeaders});
          return this.http.post('api/V1/Statement/QueryDocument', queryString, options)
            .map(data =>  {return this.extractData(data);},(statements => {
                  return statements.map(statement => new Statement(statement));}))
            .catch(this.handleError);
        }

private extractData(res: Response) {
        let body = res.json();
        console.log(body);
        return body;
    }

    private handleError (error: Response | any) {
        console.error(error.message || error);
        console.log("error");
        return Observable.throw(error.status);
    }

First component:

getSources() {
      this.sourceDisplayService.getSources().subscribe(sources => {this.sources = sources;});
    }
onRowSelect(event) {
this.sourceDisplayService.changeSource(this.source);
}

Second component:

 this.subscription = this.sourceDisplayService.currentSource.subscribe(source => this.source = source);

Body:
At first, I suggest you to store the full api result in your behaviorSubject:

private _sources = new BehaviorSubject<Source[]>([]);
public sources = this._sources.asObservable();

initData() {
  ...
  this.http.post('api/V1/Statement/QueryDocument', queryString, options)
  .subscribe(result => { this._sources.next(result); }
}

Now, to avoid a double subscription, you can bind the content of clicked source as input on the second component.
The implementation depends of the hierarchy of your components: is the second component child of the first, or they are both at the same level?

In case of same level components: Bind click event on the first to store the source row in a parent variable. Then bind the parent source variable to the second component:

<component-1 (click)="currSource=source" *ngFor="let source of service.sources | async"></component-1>

<component-2 [source]="currSource"></component-2>

In case of component 2 child of component 1:
do the same but store the row source in the component 1 and bind it directly to the child component.

You can now display the content of source without subscribe to an other subject.


问:
How do I install a font on a user's machine in VB.NET so applications like Word can use it?
Need to install a font on all user's machines that will use the application I am writing which creates custom documents in Word.  It's a barcode font.

I've successfully added the font to my solution and set its build action to Embedded Resource and have also successfully written code to check if the font is already installed on the user's system.

Now I just need to figure out how to extract the font from my solution and install it onto the user's machine as if they installed the font themselves for use in Office applications, etc.

Most of the examples I've found out there are for using the font within the VB.NET application instead of outside it and the one's I have found which seem to fit my purpose aren't working for me.

答:
Copy the font into the Windows font folder and then you need to get the font added to the registry. I've not tried this myself, but I think it's possible to do this by opening the font using the ShellExecuteA api in a similar way to as seen here.

Here's a vbscript way of doing it that might be useful as a starting point since you might be able to use similar syntax and functions in VB.Net: Hey, Scripting Guy! How Can I Install Fonts Using a Script?

ContentLicense: CC BY-SA 2.5


问:
Spring Boot and Mockito verify always true
I have a test in which I want to verify that a method was called with given parameters:

```<code>    @Autowired
    private Client client;

    @Autowired
    private OtherClient otherClient;

    @Test
    public void test() {
        client.push();

        Mockito.verify(otherClient).publishReset(
            Mockito.anyString(),
            Mockito.argThat(l -> l.size() == 3)
        );
    }
</code>```

Problem is that Mockito.verify doesn't fail at all, I can replace l -> l.size() == 3 with any other size match and given test will always pass. How is it even possible for verify to always pass whatever I pass to argThat?

Full example below:

```<code>@EnableConfigurationProperties
@TestExecutionListeners(listeners = {
    DirtiesContextTestExecutionListener.class,
    DirtiesContextBeforeModesTestExecutionListener.class,
    ServletTestExecutionListener.class,
    DependencyInjectionTestExecutionListener.class,
    MockitoTestExecutionListener.class,
    TransactionalTestExecutionListener.class,
    WithSecurityContextTestExecutionListener.class
})
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
@EnableAspectJAutoProxy(proxyTargetClass = true)
@ContextConfiguration(
    loader = SpringBootContextLoader.class,
    classes = {MyApp.class, IntegrationTestContext.class})
@RunWith(SpringRunner.class)
public class FooIT {
    @Autowired
    private Client client;

    @Autowired
    private OtherClient otherClient;

    @Test
    public void test() {
        client.push();

        Mockito.verify(otherClient).publishReset(
            Mockito.anyString(),
            Mockito.argThat(l -> l.size() == 3)
        );
    }
}
</code>```

And a configuration class:

```<code>@Configuration
@MockBeans({
    @MockBean(OtherClient.class),
})
public class IntegrationTestContext {
}
</code>```

Is there something that I'm doing wrong? Is Spring interfering with mockito somehow?

答:
Problem was in garbage collector, I created a large list l that container a lot of objects (> 30k with many fields), when I reduced the size to e.g. 100 everything started to work correctly.

So basically: don't force mockito to work with objects that take too much memory (probably some kind of weak reference is used), e.g. reduce the size of lists.

Body:
I have a test in which I want to verify that a method was called with given parameters:

    @Autowired
    private Client client;

    @Autowired
    private OtherClient otherClient;

    @Test
    public void test() {
        client.push();

        Mockito.verify(otherClient).publishReset(
            Mockito.anyString(),
            Mockito.argThat(l -> l.size() == 3)
        );
    }

Problem is that Mockito.verify doesn't fail at all, I can replace l -> l.size() == 3 with any other size match and given test will always pass. How is it even possible for verify to always pass whatever I pass to argThat?

Full example below:

@EnableConfigurationProperties
@TestExecutionListeners(listeners = {
    DirtiesContextTestExecutionListener.class,
    DirtiesContextBeforeModesTestExecutionListener.class,
    ServletTestExecutionListener.class,
    DependencyInjectionTestExecutionListener.class,
    MockitoTestExecutionListener.class,
    TransactionalTestExecutionListener.class,
    WithSecurityContextTestExecutionListener.class
})
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
@EnableAspectJAutoProxy(proxyTargetClass = true)
@ContextConfiguration(
    loader = SpringBootContextLoader.class,
    classes = {MyApp.class, IntegrationTestContext.class})
@RunWith(SpringRunner.class)
public class FooIT {
    @Autowired
    private Client client;

    @Autowired
    private OtherClient otherClient;

    @Test
    public void test() {
        client.push();

        Mockito.verify(otherClient).publishReset(
            Mockito.anyString(),
            Mockito.argThat(l -> l.size() == 3)
        );
    }
}

And a configuration class:

@Configuration
@MockBeans({
    @MockBean(OtherClient.class),
})
public class IntegrationTestContext {
}

Is there something that I'm doing wrong? Is Spring interfering with mockito somehow?


问:
employee daily sales submission form with respect to ID
After login, an employee has to update his daily product sales. For the purpose I have made 02 tables named registration and dailysales. Table registration verifies the userID and password for login of user and has link to enter daily sales in 'dailysales' table. How can I insert the userID of logged-in user from table 'registration' to table 'dailysales' automatically. Note: In Table 'dailysales' employee also has to put daily sales of products from html form. In below coding how can i add userID and user Name of logged-in user automatically alongwith entry of products.

coding for dailysales is as under:-

```<code><?php
require('config.php');

//Start the Session
session_start();

if((isset($_POST['diaper']) && !empty($_POST['diaper']))
&& (isset($_POST['babylotion']) && !empty($_POST['babylotion']))
&& (isset($_POST['nfacewash']) && !empty($_POST['nfacewash']))
&& (isset($_POST['facewash']) && !empty($_POST['facewash']))
&& (isset($_POST['hremover']) && !empty($_POST['hremover']))){
$Diaper = $_POST ['diaper'];
$BabyLotion = $_POST ['babylotion'];
$Neem_fw = $_POST ['nfacewash'];
$Facewash = $_POST ['facewash'];
$Hair_remover = $_POST ['hremover'];
}
$sql= "INSERT INTO dailyrecord (babydiaper,babylotion,hairremover,neemfw,neetfw) VALUES ('$Diaper','$BabyLotion','$Neem_fw','$Facewash','$Hair_remover')";

if (mysqli_query ($connection, $sql)){
    echo '<script>alert("Congratulations! You Have Successfully added your sale!");</script>';
    }
else{
        echo '<script>alert("Sorry! Please fill the fields marked with *!");</script>';

    }

?>
</code>```

Coding for login is as under:-

```<code><?php

//Start the Session
session_start();
require('config.php');

// If the form is submitted or not.
// If the form is submitted
if (isset($_POST['id']) and isset($_POST['password'])){
// Assigning posted values to variables.
$E_id = $_POST['id'];
$P_word = $_POST['password'];

// Check if username is empty
    if(empty(trim($_POST["id"]))){
        $username_err = 'Please enter username.';
    } else{
        $U_name = trim($_POST["id"]);
    }

    // Check if password is empty
    if(empty(trim($_POST['password']))){
        $password_err = 'Please enter your password.';
    } else{
        $P_word = trim($_POST['password']);
    }

// Checking the values are existing in the database or not
$query = "SELECT * FROM registeration WHERE employee_id='$E_id' and password='$P_word'";

$result = mysqli_query($connection, $query);
$count = mysqli_num_rows($result);
// If the posted values are equal to the database values, then session will be created for the user.
if ($count == 1){
$_SESSION['id'] = $E_id;
}else{
//If the login credentials doesn't match, he will be shown with an error message.
$fmsg = "Invalid Login Credentials.";
}
}
//if the user is logged in Greets the user with message
if (isset($_SESSION['id'])){
$E_id = $_SESSION['id'];
echo "<center><table border='2' style='background-color:#FFFFFF;border-collapse:collapse;border:2px solid #6699FF;color:#000000;width:60%'>
<tr>
<th>Distributor</th>
<th>Designation</th>
<th>City</th>
<th>Visiting Area</th>
</tr>";

while($row = mysqli_fetch_array($result))
{
echo "<tr\t\t\t>";
echo "<td>" . $row['emp_name'] . "&nbsp". $row['f_name'] . "</td>";
echo "<td>" . $row['designation'] . "</td>";
echo "<td>" . $row['city'] . "</td>";
echo "<td>" . $row['varea'] . "</td>";
echo "</tr>";
}
echo "</center></table>";
echo "<br>";
echo "<a href='logout.php'>Logout</a>";
}
else{

echo '<center>Invalied Username or Password</center>';
}
?>
</code>```

答:
As the user only gets the opportunity to add a record after a successful login there is the session variable with his/her ID available to use for insertion into sales record. Assumed that the dailyrecord or dailysales table (?which?) has a column for the user ID called employee_id then you could try something like this.

```<code><?php

    require('config.php');
    session_start();

    $babydiaper = !empty( $_POST['diaper'] ) ? $_POST['diaper'] : false;
    $babylotion = !empty( $_POST['babylotion'] ) ? $_POST['babylotion'] : false;
    $neemfw = !empty( $_POST['nfacewash'] ) ? $_POST['nfacewash'] : false;
    $neetfw = !empty( $_POST['facewash'] ) ? $_POST['facewash'] : false;
    $hairremover = !empty( $_POST['hremover'] ) ? $_POST['hremover'] : false;

    if( $babydiaper && $babylotion && $neemfw && $neetfw && $hairremover && isset( $_SESSION['id'] ) ){

        $sql='insert into `dailyrecord` ( `employee_id`, `babydiaper`, `babylotion`, `hairremover`, `neemfw`, `neetfw` ) values (?,?,?,?,?,?)';
        $stmt=$connection->prepare( $sql );

        if( $stmt ){

            $id=$_SESSION['id'];
            $stmt->bind_param('isssss', $id, $babydiaper, $babylotion, $hairremover, $neemfw, $neetfw );

            $message = $stmt->execute() ? 'Congratulations - the sale was added' : 'Bogus - the sale could not be added';
            $stmt->close();
            $connection->close();

        } else {
            $message='Sorry - there was a database problem. Please contact the administrator';
        }
    } else {
        $message='One of more fields was empty...';
    }

    echo "<script>alert('$message');</script>";
?>
</code>```

Body:
After login, an employee has to update his daily product sales. For the purpose I have made 02 tables named registration and dailysales. Table registration verifies the userID and password for login of user and has link to enter daily sales in 'dailysales' table. How can I insert the userID of logged-in user from table 'registration' to table 'dailysales' automatically. Note: In Table 'dailysales' employee also has to put daily sales of products from html form. In below coding how can i add userID and user Name of logged-in user automatically alongwith entry of products.

coding for dailysales is as under:-

<?php
require('config.php');

//Start the Session
session_start();

if((isset($_POST['diaper']) && !empty($_POST['diaper']))
&& (isset($_POST['babylotion']) && !empty($_POST['babylotion']))
&& (isset($_POST['nfacewash']) && !empty($_POST['nfacewash']))
&& (isset($_POST['facewash']) && !empty($_POST['facewash']))
&& (isset($_POST['hremover']) && !empty($_POST['hremover']))){
$Diaper = $_POST ['diaper'];
$BabyLotion = $_POST ['babylotion'];
$Neem_fw = $_POST ['nfacewash'];
$Facewash = $_POST ['facewash'];
$Hair_remover = $_POST ['hremover'];
}
$sql= "INSERT INTO dailyrecord (babydiaper,babylotion,hairremover,neemfw,neetfw) VALUES ('$Diaper','$BabyLotion','$Neem_fw','$Facewash','$Hair_remover')";

if (mysqli_query ($connection, $sql)){
    echo '';
    }
else{
        echo '';

    }

?>

Coding for login is as under:-

<?php

//Start the Session
session_start();
require('config.php');

// If the form is submitted or not.
// If the form is submitted
if (isset($_POST['id']) and isset($_POST['password'])){
// Assigning posted values to variables.
$E_id = $_POST['id'];
$P_word = $_POST['password'];

// Check if username is empty
    if(empty(trim($_POST["id"]))){
        $username_err = 'Please enter username.';
    } else{
        $U_name = trim($_POST["id"]);
    }

    // Check if password is empty
    if(empty(trim($_POST['password']))){
        $password_err = 'Please enter your password.';
    } else{
        $P_word = trim($_POST['password']);
    }

// Checking the values are existing in the database or not
$query = "SELECT * FROM registeration WHERE employee_id='$E_id' and password='$P_word'";

$result = mysqli_query($connection, $query);
$count = mysqli_num_rows($result);
// If the posted values are equal to the database values, then session will be created for the user.
if ($count == 1){
$_SESSION['id'] = $E_id;
}else{
//If the login credentials doesn't match, he will be shown with an error message.
$fmsg = "Invalid Login Credentials.";
}
}
//if the user is logged in Greets the user with message
if (isset($_SESSION['id'])){
$E_id = $_SESSION['id'];
echo "

Distributor
Designation
City
Visiting Area

";

while($row = mysqli_fetch_array($result))
{
echo "
";
echo "" . $row['emp_name'] . "&nbsp". $row['f_name'] . "	";
echo "" . $row['designation'] . "	";
echo "" . $row['city'] . "	";
echo "" . $row['varea'] . "	";
echo "
";
}
echo "
";
echo "
";
echo "Logout";
}
else{

echo 'Invalied Username or Password';
}
?>

Body:
As the user only gets the opportunity to add a record after a successful login there is the session variable with his/her ID available to use for insertion into sales record. Assumed that the dailyrecord or dailysales table (?which?) has a column for the user ID called employee_id then you could try something like this.

<?php

    require('config.php');
    session_start();

    $babydiaper = !empty( $_POST['diaper'] ) ? $_POST['diaper'] : false;
    $babylotion = !empty( $_POST['babylotion'] ) ? $_POST['babylotion'] : false;
    $neemfw = !empty( $_POST['nfacewash'] ) ? $_POST['nfacewash'] : false;
    $neetfw = !empty( $_POST['facewash'] ) ? $_POST['facewash'] : false;
    $hairremover = !empty( $_POST['hremover'] ) ? $_POST['hremover'] : false;

    if( $babydiaper && $babylotion && $neemfw && $neetfw && $hairremover && isset( $_SESSION['id'] ) ){

        $sql='insert into `dailyrecord` ( `employee_id`, `babydiaper`, `babylotion`, `hairremover`, `neemfw`, `neetfw` ) values (?,?,?,?,?,?)';
        $stmt=$connection->prepare( $sql );

        if( $stmt ){

            $id=$_SESSION['id'];
            $stmt->bind_param('isssss', $id, $babydiaper, $babylotion, $hairremover, $neemfw, $neetfw );

            $message = $stmt->execute() ? 'Congratulations - the sale was added' : 'Bogus - the sale could not be added';
            $stmt->close();
            $connection->close();

        } else {
            $message='Sorry - there was a database problem. Please contact the administrator';
        }
    } else {
        $message='One of more fields was empty...';
    }

    echo "<script>alert('$message');</script>";
?>


问:
Receiving multiple lines turn by turn over a socket at client side
I am sending a file line by line over socket using while loop. What should be coded on the client side that on each iteration at server side when a string is sent, it is also received on each iteration of while loop on client side?

My Server side code:

```<code>File file = new File("Text.txt");
Scanner scan = new Scanner(file);
while(scan.hasNextLine()){
String str = scan.nextLine();
pw.println(str);
}
</code>```

Using PrintWriter's object pw, I am sending data over socket. Please mention approach for receiving side.

Here is the client side:

```<code>String str = br.readLine();
System.out.println(str);
</code>```

答:
BufferedReader.readLine() returns null at end-of-stream, so the common idiom is to perform read inside the condition part.

```<code>String str = null;
while((str = br.readLine()) != null) {
    // do something with str
}
</code>```

Body:
I am sending a file line by line over socket using while loop. What should be coded on the client side that on each iteration at server side when a string is sent, it is also received on each iteration of while loop on client side?

My Server side code:

File file = new File("Text.txt");
Scanner scan = new Scanner(file);
while(scan.hasNextLine()){
String str = scan.nextLine();
pw.println(str);
}

Using PrintWriter's object pw, I am sending data over socket. Please mention approach for receiving side.

Here is the client side:

String str = br.readLine();
System.out.println(str);

Body:
BufferedReader.readLine() returns null at end-of-stream, so the common idiom is to perform read inside the condition part.

String str = null;
while((str = br.readLine()) != null) {
    // do something with str
}


问:
VUGen with SAPGUI protocol
This is first time I have used SAPGUI protocol with VUGen. I have recorded a script in VUGen using SAPGUI protocol. The process I have recorded is VA01 "creating sales order". While replaying the script I am getting below errors directly without opening sap logon:

Error:  line 2 contains 8 columns instead of 6 Error: Table
  'C:\Users\Administrator\Documents\VuGen\Scripts\VA01\data_1.dat'
  cannot be opened. Error code is '-4'. Warning: Extension parameng.dll
  reports error -4 on call to function ExtPerProcessInitialize Error:
  Thread Context: Call to service of the driver failed, reason - thread
  context wasn't initialized on this thread.

答:
I have tried myself recording the "VA01 - Create Sales Order" process and was able to replay it successfully.

I am using SAP 7.40 and VuGen 12.55.

Could you post the script you've recorded?

Also, you can view the script I've recorded here: https://pastebin.com/DkFD8W5J

```<code>Action()
{

sapgui_open_connection_ex(connection_string1,
    "",
    "con[0]");

sapgui_select_active_connection("con[0]");

sapgui_select_active_session("ses[0]");

sapgui_select_active_window("wnd[0]");

sapgui_window_resize("149",
    "25",
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui104",
    END_OPTIONAL);

/*Before running script, enter password in place of asterisks in logon function*/

lr_think_time(4);

sapgui_logon("NWBCUSER",
    "mercury",
    "800",
    "EN",
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1012",
    END_OPTIONAL);

sapgui_tree_set_selected_node("VA01 - Create Sales Order",
    shell1,
    "F00003",
    BEGIN_OPTIONAL,
        "AdditionalNodeInfo=Favorites;VA01 - Create Sales Order",
        "AdditionalInfo=sapgui1013",
    END_OPTIONAL);

sapgui_tree_double_click_node("VA01 - Create Sales Order",
    shell1,
    "F00003",
    BEGIN_OPTIONAL,
        "AdditionalNodeInfo=Favorites;VA01 - Create Sales Order",
        "AdditionalInfo=sapgui1014",
    END_OPTIONAL);

lr_think_time(4);

sapgui_set_text("VBAK-AUART",
    "12",
    ctxtVBAK1,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1017",
    END_OPTIONAL);

sapgui_set_text("Sales Organization",
    "ss",
    ctxtVBAK2,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1018",
    END_OPTIONAL);

sapgui_set_focus(ctxtVBAK2,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1019",
    END_OPTIONAL);

sapgui_send_vkey(F4,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1021",
    END_OPTIONAL);

sapgui_select_active_window("wnd[1]");

sapgui_window_scroll_to_row("0",
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1025",
    END_OPTIONAL);

sapgui_set_focus(lbl1,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1024",
    END_OPTIONAL);

sapgui_send_vkey(F2,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1028",
    END_OPTIONAL);

sapgui_select_active_window("wnd[0]");

sapgui_set_focus(ctxtVBAK3,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1031",
    END_OPTIONAL);

sapgui_send_vkey(F4,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1033",
    END_OPTIONAL);

sapgui_select_active_window("wnd[1]");

sapgui_window_scroll_to_row("0",
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1037",
    END_OPTIONAL);

sapgui_set_focus(lbl2,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1036",
    END_OPTIONAL);

sapgui_send_vkey(F2,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1040",
    END_OPTIONAL);

sapgui_select_active_window("wnd[0]");

sapgui_set_focus(ctxtVBAK4,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1043",
    END_OPTIONAL);

sapgui_send_vkey(F4,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1045",
    END_OPTIONAL);

sapgui_select_active_window("wnd[1]");

sapgui_window_scroll_to_row("0",
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1049",
    END_OPTIONAL);

sapgui_set_focus(lbl3,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1048",
    END_OPTIONAL);

sapgui_send_vkey(F2,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1052",
    END_OPTIONAL);

sapgui_select_active_window("wnd[0]");

sapgui_set_focus(ctxtVBAK5,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1055",
    END_OPTIONAL);

sapgui_send_vkey(F4,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1057",
    END_OPTIONAL);

sapgui_select_active_window("wnd[1]");

sapgui_press_button("Continue   (Enter)",
    btn1,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1060",
    END_OPTIONAL);

sapgui_press_button("Continue   (Enter)",
    btn1,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1063",
    END_OPTIONAL);

sapgui_set_focus(ctxtG_SELFLD_TAB1,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1066",
    END_OPTIONAL);

sapgui_send_vkey(F2,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1068",
    END_OPTIONAL);

sapgui_select_active_window("wnd[2]");

sapgui_window_close(
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1071",
    END_OPTIONAL);

sapgui_select_active_window("wnd[1]");

sapgui_set_focus(txtG_SELFLD_TAB1,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1074",
    END_OPTIONAL);

sapgui_send_vkey(F2,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1076",
    END_OPTIONAL);

sapgui_select_active_window("wnd[2]");

sapgui_grid_select_cell("'Sales Office' (2, Description)",
    shell2,
    "2",
    "TEXT",
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1079",
    END_OPTIONAL);

sapgui_grid_select_rows("'Sales Office', 2",
    shell2,
    "2",
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1080",
    END_OPTIONAL);

sapgui_grid_double_click_current_cell("'Sales Office' (2, Description)",
    shell2,
    BEGIN_OPTIONAL,
        "CurrentRow=2",
        "CurrentCell=TEXT",
        "AdditionalInfo=sapgui1081",
    END_OPTIONAL);

sapgui_select_active_window("wnd[1]");

sapgui_set_focus(txtG_SELFLD_TAB1,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1084",
    END_OPTIONAL);

sapgui_press_button("Cancel   (F12)",
    btn2,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1086",
    END_OPTIONAL);

sapgui_select_active_window("wnd[0]");

sapgui_send_vkey(F4,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1089",
    END_OPTIONAL);

sapgui_select_active_window("wnd[1]");

sapgui_window_close(
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1092",
    END_OPTIONAL);

sapgui_select_active_window("wnd[0]");

sapgui_status_bar_get_text("paramStatusBarText",
    BEGIN_OPTIONAL,
        "Recorded status bar text: Choose a valid function",
        "AdditionalInfo=sapgui1097",
    END_OPTIONAL);

lr_think_time(6);

sapgui_set_text("Sales Office",
    "1",
    ctxtVBAK5,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1098",
    END_OPTIONAL);

sapgui_set_text("Sales Group",
    "2",
    ctxtVBAK6,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1099",
    END_OPTIONAL);

sapgui_set_focus(ctxtVBAK6,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui10100",
    END_OPTIONAL);

sapgui_press_button("Back   (F3)",
    btn3,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui10102",
    END_OPTIONAL);

sapgui_press_button("Log off   (Shift+F3)",
    btn4,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui10105",
    END_OPTIONAL);

sapgui_select_active_window("wnd[1]");

sapgui_press_button("Yes",
    btnSPOP1,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui10108",
    END_OPTIONAL);

return 0;
</code>```

}

Title: VUGen with SAPGUI protocol

Body:
I have tried myself recording the "VA01 - Create Sales Order" process and was able to replay it successfully.

I am using SAP 7.40 and VuGen 12.55.

Could you post the script you've recorded?

Also, you can view the script I've recorded here: https://pastebin.com/DkFD8W5J

Action()
{

sapgui_open_connection_ex(connection_string1,
    "",
    "con[0]");

sapgui_select_active_connection("con[0]");

sapgui_select_active_session("ses[0]");

sapgui_select_active_window("wnd[0]");

sapgui_window_resize("149",
    "25",
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui104",
    END_OPTIONAL);

/*Before running script, enter password in place of asterisks in logon function*/

lr_think_time(4);

sapgui_logon("NWBCUSER",
    "mercury",
    "800",
    "EN",
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1012",
    END_OPTIONAL);

sapgui_tree_set_selected_node("VA01 - Create Sales Order",
    shell1,
    "F00003",
    BEGIN_OPTIONAL,
        "AdditionalNodeInfo=Favorites;VA01 - Create Sales Order",
        "AdditionalInfo=sapgui1013",
    END_OPTIONAL);

sapgui_tree_double_click_node("VA01 - Create Sales Order",
    shell1,
    "F00003",
    BEGIN_OPTIONAL,
        "AdditionalNodeInfo=Favorites;VA01 - Create Sales Order",
        "AdditionalInfo=sapgui1014",
    END_OPTIONAL);

lr_think_time(4);

sapgui_set_text("VBAK-AUART",
    "12",
    ctxtVBAK1,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1017",
    END_OPTIONAL);

sapgui_set_text("Sales Organization",
    "ss",
    ctxtVBAK2,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1018",
    END_OPTIONAL);

sapgui_set_focus(ctxtVBAK2,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1019",
    END_OPTIONAL);

sapgui_send_vkey(F4,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1021",
    END_OPTIONAL);

sapgui_select_active_window("wnd[1]");

sapgui_window_scroll_to_row("0",
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1025",
    END_OPTIONAL);

sapgui_set_focus(lbl1,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1024",
    END_OPTIONAL);

sapgui_send_vkey(F2,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1028",
    END_OPTIONAL);

sapgui_select_active_window("wnd[0]");

sapgui_set_focus(ctxtVBAK3,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1031",
    END_OPTIONAL);

sapgui_send_vkey(F4,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1033",
    END_OPTIONAL);

sapgui_select_active_window("wnd[1]");

sapgui_window_scroll_to_row("0",
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1037",
    END_OPTIONAL);

sapgui_set_focus(lbl2,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1036",
    END_OPTIONAL);

sapgui_send_vkey(F2,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1040",
    END_OPTIONAL);

sapgui_select_active_window("wnd[0]");

sapgui_set_focus(ctxtVBAK4,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1043",
    END_OPTIONAL);

sapgui_send_vkey(F4,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1045",
    END_OPTIONAL);

sapgui_select_active_window("wnd[1]");

sapgui_window_scroll_to_row("0",
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1049",
    END_OPTIONAL);

sapgui_set_focus(lbl3,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1048",
    END_OPTIONAL);

sapgui_send_vkey(F2,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1052",
    END_OPTIONAL);

sapgui_select_active_window("wnd[0]");

sapgui_set_focus(ctxtVBAK5,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1055",
    END_OPTIONAL);

sapgui_send_vkey(F4,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1057",
    END_OPTIONAL);

sapgui_select_active_window("wnd[1]");

sapgui_press_button("Continue   (Enter)",
    btn1,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1060",
    END_OPTIONAL);

sapgui_press_button("Continue   (Enter)",
    btn1,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1063",
    END_OPTIONAL);

sapgui_set_focus(ctxtG_SELFLD_TAB1,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1066",
    END_OPTIONAL);

sapgui_send_vkey(F2,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1068",
    END_OPTIONAL);

sapgui_select_active_window("wnd[2]");

sapgui_window_close(
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1071",
    END_OPTIONAL);

sapgui_select_active_window("wnd[1]");

sapgui_set_focus(txtG_SELFLD_TAB1,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1074",
    END_OPTIONAL);

sapgui_send_vkey(F2,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1076",
    END_OPTIONAL);

sapgui_select_active_window("wnd[2]");

sapgui_grid_select_cell("'Sales Office' (2, Description)",
    shell2,
    "2",
    "TEXT",
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1079",
    END_OPTIONAL);

sapgui_grid_select_rows("'Sales Office', 2",
    shell2,
    "2",
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1080",
    END_OPTIONAL);

sapgui_grid_double_click_current_cell("'Sales Office' (2, Description)",
    shell2,
    BEGIN_OPTIONAL,
        "CurrentRow=2",
        "CurrentCell=TEXT",
        "AdditionalInfo=sapgui1081",
    END_OPTIONAL);

sapgui_select_active_window("wnd[1]");

sapgui_set_focus(txtG_SELFLD_TAB1,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1084",
    END_OPTIONAL);

sapgui_press_button("Cancel   (F12)",
    btn2,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1086",
    END_OPTIONAL);

sapgui_select_active_window("wnd[0]");

sapgui_send_vkey(F4,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1089",
    END_OPTIONAL);

sapgui_select_active_window("wnd[1]");

sapgui_window_close(
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1092",
    END_OPTIONAL);

sapgui_select_active_window("wnd[0]");

sapgui_status_bar_get_text("paramStatusBarText",
    BEGIN_OPTIONAL,
        "Recorded status bar text: Choose a valid function",
        "AdditionalInfo=sapgui1097",
    END_OPTIONAL);

lr_think_time(6);

sapgui_set_text("Sales Office",
    "1",
    ctxtVBAK5,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1098",
    END_OPTIONAL);

sapgui_set_text("Sales Group",
    "2",
    ctxtVBAK6,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui1099",
    END_OPTIONAL);

sapgui_set_focus(ctxtVBAK6,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui10100",
    END_OPTIONAL);

sapgui_press_button("Back   (F3)",
    btn3,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui10102",
    END_OPTIONAL);

sapgui_press_button("Log off   (Shift+F3)",
    btn4,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui10105",
    END_OPTIONAL);

sapgui_select_active_window("wnd[1]");

sapgui_press_button("Yes",
    btnSPOP1,
    BEGIN_OPTIONAL,
        "AdditionalInfo=sapgui10108",
    END_OPTIONAL);

return 0;

}


问:
BCmath php 64bit
i'm using BCmath to do math with 64 bit unsigned integers, i want to make a bcmath-object to a normal int (high, low part) how can i achieve that ?

Thank you for your help

答:
The inbuilt BCMath functions don't deal with BCMath objects as such, they just process on strings to achieve arbitrary precision computation.  So you can convert back to a native php int with a normal cast.

```<code>$val = (int) bcmod( bcpow( "9392", "394" ), "100" );
</code>```

From http://php.net/manual/en/book.bc.php, method signatures are

```<code>string bcmod ( string $left_operand , string $modulus )
string bcpow ( string $left_operand , string $right_operand [, int $scale ] )
</code>```

Title: BCmath php 64bit

Body:
The inbuilt BCMath functions don't deal with BCMath objects as such, they just process on strings to achieve arbitrary precision computation.  So you can convert back to a native php int with a normal cast.

$val = (int) bcmod( bcpow( "9392", "394" ), "100" );

From http://php.net/manual/en/book.bc.php, method signatures are

string bcmod ( string $left_operand , string $modulus )
string bcpow ( string $left_operand , string $right_operand [, int $scale ] )


问:
Mock with Mockito return a InvocationTargetException
I'm writing some unit test and I stumble accross this strange "bug" which prevent me from running my unit test.

When I run the "when(...).thenReturn(...)", I receive a InvocationTargetException. Then strange things is that when I debug, it goes into the real object and crash on a null member. When I debug other "when", it goes in a function called "Intercept" which prevent to go in the real code... I don't understand what is different with this object and how to prevent this weird behavior.

Here is my unit test:

```<code>@Test
public void getSyncStatusShouldReturnValueFromDiskWhenNotRunning() throws IOException {
    //Arrange
    when(updater.isDone()).thenReturn(true);
    when(brandSyncUpdater.isDone()).thenReturn(true); //This is where it throw error
    when(stationSyncUpdater.isDone()).thenReturn(true);

    //Act
    //Assert
}
</code>```

Here is my setUp() and member section of my unit class test

```<code>private Updater updater;
private BrandSyncUpdater brandSyncUpdater;
private StationSyncUpdater stationSyncUpdater;

@Before
public void setUp() {
    updater = mock(Updater.class);
    brandSyncUpdater = mock(BrandSyncUpdater.class);
    stationSyncUpdater = mock(StationSyncUpdater.class);
}
</code>```

I don't know if it's related but the BrandSyncUpdater and StationSyncUpdater both have a parent called SyncUpdater where the isDone() function is located.

EDIT

Hierarchy of class

Updater is a class on its own

BrandSyncUpdater and StationSyncUpdater are extending SyncUpdater

Updater isDone() signature and code:

```<code>public boolean isDone() {
    return states.isEmpty();
}
</code>```

SyncUpdater isDone() signature and code:

```<code>public boolean isDone() {
    return currentStates.isEmpty();
}
</code>```

EDIT 2

Here is the stack traces of the error in the console. You'll notice that the error here is a "NullPointerException" because it try to use the variable currentStates. But when debugging, the error thrown by mockito is InvocationTargetException.

```<code>java.lang.NullPointerException
    at com.stingray360.clap.synchronizer.contentcontroller.queue.SyncUpdater.isDone(SyncUpdater.java:117)
    at com.stingray360.clap.synchronizer.contentcontroller.queue.BrandSyncUpdater.isDone(BrandSyncUpdater.java:15)
    at com.stingray360.clap.synchronizer.contentcontroller.SyncDispatcherTest.getSyncStatusShouldReturnValueFromDiskWhenNotRunning(SyncDispatcherTest.java:190)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:68)
</code>```

答:
I also got this error. In my case i missed <strong>@RunWith(PowerMockRunner.class)</strong> for my Class (i know it is silly mistake, but wasted few hours troubleshooting everything else :) ).  </p>

```<code>@RunWith(PowerMockRunner.class)
public class SimpleServiceUpgradeManagerTestNotUsed {
//Class content

}
</code>```

Body:
I'm writing some unit test and I stumble accross this strange "bug" which prevent me from running my unit test.

When I run the "when(...).thenReturn(...)", I receive a InvocationTargetException. Then strange things is that when I debug, it goes into the real object and crash on a null member. When I debug other "when", it goes in a function called "Intercept" which prevent to go in the real code... I don't understand what is different with this object and how to prevent this weird behavior.

Here is my unit test:

@Test
public void getSyncStatusShouldReturnValueFromDiskWhenNotRunning() throws IOException {
    //Arrange
    when(updater.isDone()).thenReturn(true);
    when(brandSyncUpdater.isDone()).thenReturn(true); //This is where it throw error
    when(stationSyncUpdater.isDone()).thenReturn(true);

    //Act
    //Assert
}

Here is my setUp() and member section of my unit class test

private Updater updater;
private BrandSyncUpdater brandSyncUpdater;
private StationSyncUpdater stationSyncUpdater;

@Before
public void setUp() {
    updater = mock(Updater.class);
    brandSyncUpdater = mock(BrandSyncUpdater.class);
    stationSyncUpdater = mock(StationSyncUpdater.class);
}

I don't know if it's related but the BrandSyncUpdater and StationSyncUpdater both have a parent called SyncUpdater where the isDone() function is located.

EDIT

Hierarchy of class

Updater is a class on its own

BrandSyncUpdater and StationSyncUpdater are extending SyncUpdater

Updater isDone() signature and code:

public boolean isDone() {
    return states.isEmpty();
}

SyncUpdater isDone() signature and code:

public boolean isDone() {
    return currentStates.isEmpty();
}

EDIT 2

Here is the stack traces of the error in the console. You'll notice that the error here is a "NullPointerException" because it try to use the variable currentStates. But when debugging, the error thrown by mockito is InvocationTargetException.

java.lang.NullPointerException
    at com.stingray360.clap.synchronizer.contentcontroller.queue.SyncUpdater.isDone(SyncUpdater.java:117)
    at com.stingray360.clap.synchronizer.contentcontroller.queue.BrandSyncUpdater.isDone(BrandSyncUpdater.java:15)
    at com.stingray360.clap.synchronizer.contentcontroller.SyncDispatcherTest.getSyncStatusShouldReturnValueFromDiskWhenNotRunning(SyncDispatcherTest.java:190)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:68)

Body:
I also got this error. In my case i missed @RunWith(PowerMockRunner.class) for my Class (i know it is silly mistake, but wasted few hours troubleshooting everything else :) ).

@RunWith(PowerMockRunner.class)
public class SimpleServiceUpgradeManagerTestNotUsed {
//Class content

}


问:
Automatically parse json attributes into a new object
I have incoming data in json format looking like this:

Raw data:

```<code>{
  "data": [{
      "id": "Device_6",
      "type": "SensingDevice",
      "Battery": {
        "type": "Number",
        "value": "4.08",
        "metadata": {
          "timestamp": {
            "type": "DateTime",
            "value": "2017-11-09T14:49:02.00Z"
          },
          "unit": {
            "type": "Text",
            "value": "voltage"
          }
        }
      },
      "DO": {
        "type": "Number",
        "value": "5.71",
        "metadata": {
          "timestamp": {
            "type": "DateTime",
            "value": "2017-11-09T14:49:02.00Z"
          },
          "unit": {
            "type": "Text",
            "value": "mg/l"
          }
        }
      },
      "Humidity": {
        "type": "Number",
        "value": "57.30",
        "metadata": {
          "timestamp": {
            "type": "DateTime",
            "value": "2017-11-09T14:49:02.00Z"
          },
          "unit": {
            "type": "Text",
            "value": "percent"
          }
        }
      },
      "PH": {
        "type": "Number",
        "value": "14.00",
        "metadata": {
          "timestamp": {
            "type": "DateTime",
            "value": "2017-11-09T14:49:02.00Z"
          }
        }
      },
      "temperature": {
        "type": "Number",
        "value": "41.00",
        "metadata": {
          "timestamp": {
            "type": "DateTime",
            "value": "2017-11-09T14:49:02.00Z"
          },
          "unit": {
            "type": "Text",
            "value": "celsius"
          }
        }
      },
      "waterTemperature": {
        "type": "Number",
        "value": "29.69",
        "metadata": {
          "timestamp": {
            "type": "DateTime",
            "value": "2017-11-09T14:49:02.00Z"
          },
          "unit": {
            "type": "Text",
            "value": "celsius"
          }
        }
      }
    }
  ],
  "subscriptionId": "59d5eeec4f3db340052d618c"
}
</code>```

For a specific application purpose, i need to transform this complex JSON into a simple key:value format.

So I'm using this code in node js with node-json-transform package:

```<code> var map_data = {
           list:'data',
            item :  { Battery: 'Battery.value',
                        DO: 'DO.value',
                        Humidity: 'Humidity.value',
                        PH: 'PH.value',
                        temperature: 'temperature.value',
                        waterTemperature: 'waterTemperature.value', },
    };
   console.log (map_data)

         var dataTransform = DataTransform(data, map_data);
         var data_result = dataTransform.transform();
</code>```

And the output looks like what I want :

```<code>[ { Battery: '4.08',
    DO: '5.71',
    Humidity: '57.30',
    PH: '14.00',
    temperature: '41.00',
    waterTemperature: '29.69' } ]
</code>```

But now, what if I don't know the name of the attributes?
So I tried to make it automatic to discover the keys:

```<code>var keys = Object.keys(data.data[0]);
var keysvalues = '';
    for (i=2; i < keys.length; i++) {
        keysvalues += keys[i]+':"'+ keys[i] + '.value",';
    }
var item = '{'+keysvalues+'}';
var map_data = {
            list:"data",
            item,
    };
 var dataTransform = DataTransform(data, map_data);
 var data_result = dataTransform.transform();
</code>```

This is not working because the object map_data.item is a "fake" object where I manually added the {}, so it is recognized like a string :

```<code>console.log(map_data)
{ list: 'data',
  item: '{Battery:"Battery.value",DO:"DO.value",Humidity:"Humidity.value",PH:"PH.value",temperature:"temperature.value",waterTemperature:"waterTemperature.value",}' }
</code>```

Can you help me on how to make the item object a real object so I can parse the JSON automatically in the format I want?

答:
So basically you want to create a map given the 'value' property of all the nested objects. This means you have to filter out the keys of your original object that aren't Objects or that don't have the 'value' prop.
Here's how I would do it (I've used ES6 to avoid verboseness).

```<code>const isObject = (o) =>
  o instanceof Object && o.constructor === Object;

const getSingleMap = (datum, prop) => {
  const mapKeys = Object.keys(datum).filter(key => isObject(datum[key]) && datum[key][prop]);
  const obj = {};
  mapKeys.forEach(key => {
    obj[key] = datum[key][prop];
  });

  return obj;
}

const getMap = (rawData, prop) =>
  rawData.data.map(datum => getSingleMap(datum, prop));
</code>```

To use it, simply call const res = getMap(rawData, 'value');.

```<code>/*
res == [
  {
    "Battery": "4.08",
    "DO": "5.71",
    "Humidity": "57.30",
    "PH": "14.00",
    "temperature": "41.00",
    "waterTemperature": "29.69"
  }
];
*/
</code>```

Below is provided a more elegant getSingleMap implementation.

```<code>getSingleMap = (datum, prop) => {
  const mapKeys = Object.keys(datum).filter(key => isObject(datum[key]) && datum[key][prop]);
  return mapKeys.reduce((acc, key) => {
    acc[key] = datum[key][prop];
    return acc;
  }, {});
}
</code>```

Update: I've also create an npm package out of this, it's called json2kv, and you can find its source here

Body:
I have incoming data in json format looking like this:

Raw data:

{
  "data": [{
      "id": "Device_6",
      "type": "SensingDevice",
      "Battery": {
        "type": "Number",
        "value": "4.08",
        "metadata": {
          "timestamp": {
            "type": "DateTime",
            "value": "2017-11-09T14:49:02.00Z"
          },
          "unit": {
            "type": "Text",
            "value": "voltage"
          }
        }
      },
      "DO": {
        "type": "Number",
        "value": "5.71",
        "metadata": {
          "timestamp": {
            "type": "DateTime",
            "value": "2017-11-09T14:49:02.00Z"
          },
          "unit": {
            "type": "Text",
            "value": "mg/l"
          }
        }
      },
      "Humidity": {
        "type": "Number",
        "value": "57.30",
        "metadata": {
          "timestamp": {
            "type": "DateTime",
            "value": "2017-11-09T14:49:02.00Z"
          },
          "unit": {
            "type": "Text",
            "value": "percent"
          }
        }
      },
      "PH": {
        "type": "Number",
        "value": "14.00",
        "metadata": {
          "timestamp": {
            "type": "DateTime",
            "value": "2017-11-09T14:49:02.00Z"
          }
        }
      },
      "temperature": {
        "type": "Number",
        "value": "41.00",
        "metadata": {
          "timestamp": {
            "type": "DateTime",
            "value": "2017-11-09T14:49:02.00Z"
          },
          "unit": {
            "type": "Text",
            "value": "celsius"
          }
        }
      },
      "waterTemperature": {
        "type": "Number",
        "value": "29.69",
        "metadata": {
          "timestamp": {
            "type": "DateTime",
            "value": "2017-11-09T14:49:02.00Z"
          },
          "unit": {
            "type": "Text",
            "value": "celsius"
          }
        }
      }
    }
  ],
  "subscriptionId": "59d5eeec4f3db340052d618c"
}

For a specific application purpose, i need to transform this complex JSON into a simple key:value format.

So I'm using this code in node js with node-json-transform package:

 var map_data = {
           list:'data',
            item :  { Battery: 'Battery.value',
                        DO: 'DO.value',
                        Humidity: 'Humidity.value',
                        PH: 'PH.value',
                        temperature: 'temperature.value',
                        waterTemperature: 'waterTemperature.value', },
    };
   console.log (map_data)

         var dataTransform = DataTransform(data, map_data);
         var data_result = dataTransform.transform();

And the output looks like what I want :

[ { Battery: '4.08',
    DO: '5.71',
    Humidity: '57.30',
    PH: '14.00',
    temperature: '41.00',
    waterTemperature: '29.69' } ]

But now, what if I don't know the name of the attributes?
So I tried to make it automatic to discover the keys:

var keys = Object.keys(data.data[0]);
var keysvalues = '';
    for (i=2; i < keys.length; i++) {
        keysvalues += keys[i]+':"'+ keys[i] + '.value",';
    }
var item = '{'+keysvalues+'}';
var map_data = {
            list:"data",
            item,
    };
 var dataTransform = DataTransform(data, map_data);
 var data_result = dataTransform.transform();

This is not working because the object map_data.item is a "fake" object where I manually added the {}, so it is recognized like a string :

console.log(map_data)
{ list: 'data',
  item: '{Battery:"Battery.value",DO:"DO.value",Humidity:"Humidity.value",PH:"PH.value",temperature:"temperature.value",waterTemperature:"waterTemperature.value",}' }

Can you help me on how to make the item object a real object so I can parse the JSON automatically in the format I want?

Body:
So basically you want to create a map given the 'value' property of all the nested objects. This means you have to filter out the keys of your original object that aren't Objects or that don't have the 'value' prop.
Here's how I would do it (I've used ES6 to avoid verboseness).

const isObject = (o) =>
  o instanceof Object && o.constructor === Object;

const getSingleMap = (datum, prop) => {
  const mapKeys = Object.keys(datum).filter(key => isObject(datum[key]) && datum[key][prop]);
  const obj = {};
  mapKeys.forEach(key => {
    obj[key] = datum[key][prop];
  });

  return obj;
}

const getMap = (rawData, prop) =>
  rawData.data.map(datum => getSingleMap(datum, prop));

To use it, simply call const res = getMap(rawData, 'value');.

/*
res == [
  {
    "Battery": "4.08",
    "DO": "5.71",
    "Humidity": "57.30",
    "PH": "14.00",
    "temperature": "41.00",
    "waterTemperature": "29.69"
  }
];
*/

Below is provided a more elegant getSingleMap implementation.

getSingleMap = (datum, prop) => {
  const mapKeys = Object.keys(datum).filter(key => isObject(datum[key]) && datum[key][prop]);
  return mapKeys.reduce((acc, key) => {
    acc[key] = datum[key][prop];
    return acc;
  }, {});
}

Update: I've also create an npm package out of this, it's called json2kv, and you can find its source here


问:
Excel formulas Timestamp
Guys I'm having a problem.
In the current sheet.
In F1 i'm using the follow formula for date the current date.

```<code>=TEXT(NOW(), "dd-mm-yyyy")
</code>```

Sheet will auto refresh every 1 min.

Dates in each cell (A4:A53)13-11-2017,14-11-2017 date going down.
Using and if statement to see if current date is true then insert (B1) if false then write nothing. Current formula i am using.

=IF(F1=A4:A53,"B1,"")

It is always saying dates are not true, always false. Even if they are true.
Any advise please

答:
In your formula =IF(F1=A4:A53,"true","false"), the condition F1=A4:A53 will always be FALSE since you are comparing a single cell's value to a range. Also, try casting the cell values to a date using the DATE function.

Try changing your formula to:

```<code>=IF(DATE(F1)=DATE(A4),"true","false")
</code>```

Where $A$1 is the cell with today's date.

Title: Excel formulas Timestamp

Body:
Guys I'm having a problem.
In the current sheet.
In F1 i'm using the follow formula for date the current date.

=TEXT(NOW(), "dd-mm-yyyy")

Sheet will auto refresh every 1 min.

Dates in each cell (A4:A53)13-11-2017,14-11-2017 date going down.
Using and if statement to see if current date is true then insert (B1) if false then write nothing. Current formula i am using.

=IF(F1=A4:A53,"B1,"")

It is always saying dates are not true, always false. Even if they are true.
Any advise please

Body:
In your formula =IF(F1=A4:A53,"true","false"), the condition F1=A4:A53 will always be FALSE since you are comparing a single cell's value to a range. Also, try casting the cell values to a date using the DATE function.

Try changing your formula to:

=IF(DATE(F1)=DATE(A4),"true","false")

Where $A$1 is the cell with today's date.


问:
Is there difference between "catch [Exception]" and "catch" in PowerShell?
I have a script which is transferring some files via SFTP using WinSCP.

A summary of the script:

```<code>$transferfiles = @("filename 1" "filename 2")

foreach ($file in $transferfiles) {
    $file
    $transferResult = $session.PutFiles($file, "/upload/TEST/", $False,$transferOptions)
    try {
        $transferResult.Check()
    }
    catch [Exception]{
        Write-Host "$file was not transferred."
    }
}
</code>```

I just want to know if I need to use [Exception]? Why doesn't catch by itself work?

Thanks

答:
catch [Exception] is identical to catch.

So you do not need to use catch [Exception].

I have modified all official WinSCP .NET assembly examples to use just catch.

Body:
I have a script which is transferring some files via SFTP using WinSCP.

A summary of the script:

$transferfiles = @("filename 1" "filename 2")

foreach ($file in $transferfiles) {
    $file
    $transferResult = $session.PutFiles($file, "/upload/TEST/", $False,$transferOptions)
    try {
        $transferResult.Check()
    }
    catch [Exception]{
        Write-Host "$file was not transferred."
    }
}

I just want to know if I need to use [Exception]? Why doesn't catch by itself work?

Thanks


问:
How to know if there are two identical elements in the same map in Java
I used nested map,

```<code>Map<String,Map<String,List<String>>> scheduleMap = new HashMap<>();
</code>```

and I put three elements in the map, studentId, subject, major.

As examples for input,

```<code>    scheduleMap1.add("30600001", "INFO1105", "IT");
    scheduleMap1.add("30600001", "ELEC1603", "ElecEng");
    scheduleMap1.add("30600002", "INFO1103", "IT");
    scheduleMap1.add("30600003", "INFO1003", "IT");
    scheduleMap1.add("30600001", "ELEC1601", "ElecEng");
    scheduleMap1.add("30600002", "INFO1003", "IT");
    scheduleMap1.add("30600002", "ELEC1603", "ElecEng");
    scheduleMap1.add("30600001", "INFO1003", "IT");
</code>```

were put in the map.

The final purpose was that, for each student id, 30600001, 30600002 and 30600003, if there are two identical majors stored in whichever in the key, the count should be increased.

For example, as shown in the example, 30600001 has two "IT" and two "ElecEng" each as its major element. So the count should be equal to 2.

For studentId, 30600002, it has two "IT" but has only one "ElecEng" as its major element so the count should be 1.

I could achieve my goal by coding like this:

```<code>for(Entry<String, Map<String, List<String>>> studentId : scheduleMap.entrySet()) {

 for(Entry<String, List<String>> subject : studentId.getValue().entrySet())
 {
    for(String major : subject.getValue())
    {
      if(major.contains("IT"))
      {
         it++;
      } else if(major.contains("ElecEng")) {
          elec++;

        }
          if(it >= 2 || elec >= 2)
          {
            count++;
          }
    }
</code>```

however, is there any way to get the counts by not pointing out the finding major like major.contains("IT") and major.contains("ElecEng")?

I really want to get the count increased by doing like,

```<code>if(everytime key.subject.major has two identical elements)
{
   count++;
}
</code>```

Any help would be great. Thanks!

答:
Map in general don’t support two key-value set with the same key. Each and every key must be unique.
Refer to this. </p>

Body:
I used nested map,

Map<String,Map<String,List<String>>> scheduleMap = new HashMap<>();

and I put three elements in the map, studentId, subject, major.

As examples for input,

    scheduleMap1.add("30600001", "INFO1105", "IT");
    scheduleMap1.add("30600001", "ELEC1603", "ElecEng");
    scheduleMap1.add("30600002", "INFO1103", "IT");
    scheduleMap1.add("30600003", "INFO1003", "IT");
    scheduleMap1.add("30600001", "ELEC1601", "ElecEng");
    scheduleMap1.add("30600002", "INFO1003", "IT");
    scheduleMap1.add("30600002", "ELEC1603", "ElecEng");
    scheduleMap1.add("30600001", "INFO1003", "IT");

were put in the map.

The final purpose was that, for each student id, 30600001, 30600002 and 30600003, if there are two identical majors stored in whichever in the key, the count should be increased.

For example, as shown in the example, 30600001 has two "IT" and two "ElecEng" each as its major element. So the count should be equal to 2.

For studentId, 30600002, it has two "IT" but has only one "ElecEng" as its major element so the count should be 1.

I could achieve my goal by coding like this:

for(Entry<String, Map<String, List<String>>> studentId : scheduleMap.entrySet()) {

 for(Entry<String, List<String>> subject : studentId.getValue().entrySet())
 {
    for(String major : subject.getValue())
    {
      if(major.contains("IT"))
      {
         it++;
      } else if(major.contains("ElecEng")) {
          elec++;

        }
          if(it >= 2 || elec >= 2)
          {
            count++;
          }
    }

however, is there any way to get the counts by not pointing out the finding major like major.contains("IT") and major.contains("ElecEng")?

I really want to get the count increased by doing like,

if(everytime key.subject.major has two identical elements)
{
   count++;
}

Any help would be great. Thanks!


问:
How to configure delay until condition is true in Jmeter
I have a question about Jmeter delay, I created a test plan and in one step I make a call to DB using JDBC, and store the results in actual_vertica_results parameter (counts number of employees in temp table).
I want to configure Jmeter to Waite until actual_vertica_results will be 0.
(the table in DB deletes itself)
Can someone please advise how can I perform such scenario in Jmeter, today I am using constant timer for delay, and increase it manually each iteration to make sure all the data deleted.
How can I ask Jmeter making call to DB every 5 seconds and check  the results and only after all temp data deleted from the table to progress to the next step?
if someone can provide step by step scenario with PIC it will be very helpful
regards

答:
Put your JDBC Request sampler under the While Controller and use the following condition:

```<code>${__javaScript("${Actual_vertica_results}" != "0",)}
</code>```

Add Test Action sampler after your JDBC Request sampler and configure it as follows:

Target: Current Thread

Action: Pause

Duration: 5000

See Using the While Controller in JMeter article for more information.

Body:
Put your JDBC Request sampler under the While Controller and use the following condition:

${__javaScript("${Actual_vertica_results}" != "0",)}

Add Test Action sampler after your JDBC Request sampler and configure it as follows:

Target: Current Thread

Action: Pause

Duration: 5000

See Using the While Controller in JMeter article for more information.


问:
Adding items to the formRequest validator
I'm working on a project and one part of it is that users can create projects.

It is required for a project to be coupled to a user. If the user is logged in when creating a project, then there is no problem, i can just attach the project to the authenticated user, but when the user is not logged in, i have the following section in my form

In short, there are 2 radiobuttons, the 1st means "i have an account, log me in" with the login fields below it. The 2nd means "i'm a new user, create an account", which will show the correct fields to create a user.

Since this form is added to the project creation form, everything has to be validated at once.

Now i have a formRequest that handles all the validation, but i'm struggling with the login part.

When validating, i have to check the following things:

1) if the user was logged in when starting to fill in the form, but is no longer logged in when storing the data, then we have to add this to the errors array

2) if the user was not logged in when starting to fill in the form, and he choses to log in through the form a have explained above, then we need to try and log in the user when creating the project, and add a message to the errors array when the login fails "wrongs credentials has been supplied....".

I have tried with the following FormRequest:

```<code>    <?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class CreateJobsRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        if (! auth()->check()) {
            if($this->get('is_logged_in')) {
                // If we reach this, then we were logged in when starting to fill in the form
                // but are no longer when finishing the form (idle for to long, ....).
                $this->getValidatorInstance()->errors()->add('authentication', 'You were no longer authenticated when creating the project.');
            }

            if($this->get('auth_type') == 'login') {
                if(! auth()->attempt($this->getLoginParams())) {
                    // if we reach this, we have chosen to log in through the form, bu the provided details did not match our records.
                    $this->getValidatorInstance()->errors()->add('authentication', 'Failed to authenticate');
                }
            }
        }

        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'login.email'        => 'required_if:auth_type,login',
            'login.password'     => 'required_if:auth_type,login',
            'register.email'     => 'nullable|required_if:auth_type,register|email|max:255',
            'register.password'  => 'required_if:auth_type,register,confirmed|max:255',
            'register.firstname' => 'required_if:auth_type,register|max:255',
            'register.name'      => 'required_if:auth_type,register|max:255',

            'jobs.*.title'       => 'required',
            'jobs.*.description' => 'required',
            'jobs.*.category_id' => 'required|exists:job_categories,id',
            'jobs.*.location_id' => 'required|exists:job_locations,id',
            'jobs.*.profiles'    => 'required|numeric'
        ];
    }

    private function getLoginParams()
    {
        return ['email' => $this->get('login.email'), 'password' => $this->get('login.password')];
    }
}
</code>```

The most important part is in the authorize method. I'm trying to add items to the errors array, but its not working.

1) If all the other validations from the rules function pass, then i am not redirected to the creation page but the code enters the controller and a project is created.

2) if not all other validations pass, then i'm redirected to the creation page, but the errors i added in the authorize method are not added to the errors, and thus not shown on the creation page.

答:
I don't think the authorize method is the right place to put this logic.

I would add additional rules to the rules array based on the login status.

try something like this:

```<code>   public function rules()
    {
        $rules = [
            'login.email'        => 'required_if:auth_type,login',
            'login.password'     => 'required_if:auth_type,login',
            'register.email'     => 'nullable|required_if:auth_type,register|email|max:255',
            'register.password'  => 'required_if:auth_type,register,confirmed|max:255',
            'register.firstname' => 'required_if:auth_type,register|max:255',
            'register.name'      => 'required_if:auth_type,register|max:255',

            'jobs.*.title'       => 'required',
            'jobs.*.description' => 'required',
            'jobs.*.category_id' => 'required|exists:job_categories,id',
            'jobs.*.location_id' => 'required|exists:job_locations,id',
            'jobs.*.profiles'    => 'required|numeric'
        ];

        if (! auth()->check()) {
            if($this->get('is_logged_in')) {
                // If we reach this, then we were logged in when starting to fill in the form
                // but are no longer when finishing the form (idle for to long, ....).
                $rules = array_merge($rules, ['no_authentication' => 'required']);
            }

            if($this->get('auth_type') == 'login') {
                if(! auth()->attempt($this->getLoginParams())) {
                    // if we reach this, we have chosen to log in through the form, bu the provided details did not match our records.
                    $rules = array_merge($rules, ['failed_authentication' => 'required', 'Failed to authenticate']);
                }
            }
        }

        return $rules;
    }

    public function messages()
    {
        return [
          'no_authentication.required' => 'You were no longer authenticated when creating the project.',
          'failed_authentication.required' => 'Failed to authenticate'

        ];
    }
</code>```

Body:
I'm working on a project and one part of it is that users can create projects.

It is required for a project to be coupled to a user. If the user is logged in when creating a project, then there is no problem, i can just attach the project to the authenticated user, but when the user is not logged in, i have the following section in my form

In short, there are 2 radiobuttons, the 1st means "i have an account, log me in" with the login fields below it. The 2nd means "i'm a new user, create an account", which will show the correct fields to create a user.

Since this form is added to the project creation form, everything has to be validated at once.

Now i have a formRequest that handles all the validation, but i'm struggling with the login part.

When validating, i have to check the following things:

1) if the user was logged in when starting to fill in the form, but is no longer logged in when storing the data, then we have to add this to the errors array

2) if the user was not logged in when starting to fill in the form, and he choses to log in through the form a have explained above, then we need to try and log in the user when creating the project, and add a message to the errors array when the login fails "wrongs credentials has been supplied....".

I have tried with the following FormRequest:

    <?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class CreateJobsRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        if (! auth()->check()) {
            if($this->get('is_logged_in')) {
                // If we reach this, then we were logged in when starting to fill in the form
                // but are no longer when finishing the form (idle for to long, ....).
                $this->getValidatorInstance()->errors()->add('authentication', 'You were no longer authenticated when creating the project.');
            }

            if($this->get('auth_type') == 'login') {
                if(! auth()->attempt($this->getLoginParams())) {
                    // if we reach this, we have chosen to log in through the form, bu the provided details did not match our records.
                    $this->getValidatorInstance()->errors()->add('authentication', 'Failed to authenticate');
                }
            }
        }

        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'login.email'        => 'required_if:auth_type,login',
            'login.password'     => 'required_if:auth_type,login',
            'register.email'     => 'nullable|required_if:auth_type,register|email|max:255',
            'register.password'  => 'required_if:auth_type,register,confirmed|max:255',
            'register.firstname' => 'required_if:auth_type,register|max:255',
            'register.name'      => 'required_if:auth_type,register|max:255',

            'jobs.*.title'       => 'required',
            'jobs.*.description' => 'required',
            'jobs.*.category_id' => 'required|exists:job_categories,id',
            'jobs.*.location_id' => 'required|exists:job_locations,id',
            'jobs.*.profiles'    => 'required|numeric'
        ];
    }

    private function getLoginParams()
    {
        return ['email' => $this->get('login.email'), 'password' => $this->get('login.password')];
    }
}

The most important part is in the authorize method. I'm trying to add items to the errors array, but its not working.

1) If all the other validations from the rules function pass, then i am not redirected to the creation page but the code enters the controller and a project is created.

2) if not all other validations pass, then i'm redirected to the creation page, but the errors i added in the authorize method are not added to the errors, and thus not shown on the creation page.

Body:
I don't think the authorize method is the right place to put this logic.

I would add additional rules to the rules array based on the login status.

try something like this:

   public function rules()
    {
        $rules = [
            'login.email'        => 'required_if:auth_type,login',
            'login.password'     => 'required_if:auth_type,login',
            'register.email'     => 'nullable|required_if:auth_type,register|email|max:255',
            'register.password'  => 'required_if:auth_type,register,confirmed|max:255',
            'register.firstname' => 'required_if:auth_type,register|max:255',
            'register.name'      => 'required_if:auth_type,register|max:255',

            'jobs.*.title'       => 'required',
            'jobs.*.description' => 'required',
            'jobs.*.category_id' => 'required|exists:job_categories,id',
            'jobs.*.location_id' => 'required|exists:job_locations,id',
            'jobs.*.profiles'    => 'required|numeric'
        ];

        if (! auth()->check()) {
            if($this->get('is_logged_in')) {
                // If we reach this, then we were logged in when starting to fill in the form
                // but are no longer when finishing the form (idle for to long, ....).
                $rules = array_merge($rules, ['no_authentication' => 'required']);
            }

            if($this->get('auth_type') == 'login') {
                if(! auth()->attempt($this->getLoginParams())) {
                    // if we reach this, we have chosen to log in through the form, bu the provided details did not match our records.
                    $rules = array_merge($rules, ['failed_authentication' => 'required', 'Failed to authenticate']);
                }
            }
        }

        return $rules;
    }

    public function messages()
    {
        return [
          'no_authentication.required' => 'You were no longer authenticated when creating the project.',
          'failed_authentication.required' => 'Failed to authenticate'

        ];
    }


问:
Hibernate: best practice to pull all lazy collections
What I have:

```<code>@Entity
public class MyEntity {
  @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
  @JoinColumn(name = "myentiy_id")
  private List<Address> addreses;

  @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
  @JoinColumn(name = "myentiy_id")
  private List<Person> persons;

  //....
}

public void handle() {

   Session session = createNewSession();
   MyEntity entity = (MyEntity) session.get(MyEntity.class, entityId);
   proceed(session); // FLUSH, COMMIT, CLOSE session!

   Utils.objectToJson(entity); //TROUBLES, because it can't convert to json lazy collections
}
</code>```

What a problem:

The problem is that I can't pull lazy collection after session has been closed. But I also can't not close a session in proceed method.

What a solution (coarse solution):

a) Before session is closed, force hibernate to pull lazy collections

```<code>entity.getAddresses().size();
entity.getPersons().size();
</code>```

....

b) Maybe more ellegant way is to use @Fetch(FetchMode.SUBSELECT) annotation

Question:

What is a best practice/common way/more ellegant way to do it? Means convert my object to JSON.

答:
Try use Gson library to convert objects to Json

Example with servlets :

```<code>  List<Party> parties = bean.getPartiesByIncidentId(incidentId);
        String json = "";
        try {
            json = new Gson().toJson(parties);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");
        response.getWriter().write(json);
</code>```

Body:
What I have:

@Entity
public class MyEntity {
  @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
  @JoinColumn(name = "myentiy_id")
  private List<Address> addreses;

  @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
  @JoinColumn(name = "myentiy_id")
  private List<Person> persons;

  //....
}

public void handle() {

   Session session = createNewSession();
   MyEntity entity = (MyEntity) session.get(MyEntity.class, entityId);
   proceed(session); // FLUSH, COMMIT, CLOSE session!

   Utils.objectToJson(entity); //TROUBLES, because it can't convert to json lazy collections
}

What a problem:

The problem is that I can't pull lazy collection after session has been closed. But I also can't not close a session in proceed method.

What a solution (coarse solution):

a) Before session is closed, force hibernate to pull lazy collections

entity.getAddresses().size();
entity.getPersons().size();

....

b) Maybe more ellegant way is to use @Fetch(FetchMode.SUBSELECT) annotation

Question:

What is a best practice/common way/more ellegant way to do it? Means convert my object to JSON.

Body:
Try use Gson library to convert objects to Json

Example with servlets :

  List<Party> parties = bean.getPartiesByIncidentId(incidentId);
        String json = "";
        try {
            json = new Gson().toJson(parties);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");
        response.getWriter().write(json);