问:
java.lang.AssertionError: Status expected:<400> but was:<404>
Below is the controller method I'm trying to write a unit test for:

```<code>@GetMapping("/status/{uuid}")
    public ResponseEntity<StatusResponse> getStatusByUUID(@PathVariable(value = "uuid", required = true) String uuid) {
        if(uuid == null || uuid.isBlank() || uuid.isEmpty()) {
            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, Constant.UUID_VALIDATION_EXCEPTION);
        }
        logger.info("Get status request came in for UUID number: " + uuid);
        return Handler.getStatusByUUID(uuid);
    }
</code>```

Below is the unite test I'm trying to run

```<code>@Test
    public void testGetStatusWhenUUIDIsEmpty() throws Exception {
        mockMvc.perform(MockMvcRequestBuilders.get("/status/{uuid}", "")
                .characterEncoding("utf-8")
                .accept(MediaType.APPLICATION_JSON))
                .andExpect(MockMvcResultMatchers.status().isBadRequest())
                .andExpect(result -> assertTrue(result.getResolvedException() instanceof ResponseStatusException));

    }
</code>```

Below is the stack trace of the error

```<code>java.lang.AssertionError: Status expected:<400> but was:<404>
    at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:59)
    at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:122)
    at org.springframework.test.web.servlet.result.StatusResultMatchers.lambda$matcher$9(StatusResultMatchers.java:627)
    at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:212)
</code>```

Can someone help me with what I missed?
Thank you for your time.

答:
By defining @GetMapping("/status/{uuid}"), you've defined an endpoint that requires an additional path. In the tests, however, the resulting URL is /status/ which does not match the pattern of the GetMapping hence the 404.

If you modify the GetMapping to also handle URIs without the additional path, it should trigger that method.

@GetMapping(value = {"/status", "/status/{uuid}"})
public ResponseEntity<StatusResponse> getStatusByUUID(@PathVariable(value = "uuid", required = false) String uuid) { ... }
```
<p>Here was the test code I ran</p>
<pre class="lang-java prettyprint-override"><code>@RestController
public class MyController {
  @GetMapping("/foo/{var}")
  public ResponseEntity<Void> foo(@PathVariable(value = "var") String var) {
    HttpStatus status = StringUtils.hasText(var) ? HttpStatus.OK : HttpStatus.BAD_REQUEST;
    return ResponseEntity.status(status).build();
  }

  @GetMapping(value = {"/bar", "/bar/{var}"})
  public ResponseEntity<Void> bar(@PathVariable(value = "var", required = false) String var) {
    HttpStatus status = StringUtils.hasText(var) ? HttpStatus.OK : HttpStatus.BAD_REQUEST;
    return ResponseEntity.status(status).build();
  }
}
</code>```
```<code>public class MyTest {
  MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new MyController()).build();

  @Test
  public void foo() {
    MvcResult result = mockMvc.perform(get("/foo/{var}", "")).andReturn();
    assertEquals(404, result.getResponse.getStatus());
  }

  @Test
  public void bar1() {
    MvcResult result = mockMvc.perform(get("/bar/{var}", "val")).andReturn();
    assertEquals(200, result.getResponse.getStatus());
  }

  @Test
  public void bar2() {
    MvcResult result = mockMvc.perform(get("/bar/{var}", "")).andReturn();
    assertEquals(400, result.getResponse.getStatus());
  }
}
</code>```

Body:
Below is the controller method I'm trying to write a unit test for:

@GetMapping("/status/{uuid}")
    public ResponseEntity<StatusResponse> getStatusByUUID(@PathVariable(value = "uuid", required = true) String uuid) {
        if(uuid == null || uuid.isBlank() || uuid.isEmpty()) {
            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, Constant.UUID_VALIDATION_EXCEPTION);
        }
        logger.info("Get status request came in for UUID number: " + uuid);
        return Handler.getStatusByUUID(uuid);
    }

Below is the unite test I'm trying to run

@Test
    public void testGetStatusWhenUUIDIsEmpty() throws Exception {
        mockMvc.perform(MockMvcRequestBuilders.get("/status/{uuid}", "")
                .characterEncoding("utf-8")
                .accept(MediaType.APPLICATION_JSON))
                .andExpect(MockMvcResultMatchers.status().isBadRequest())
                .andExpect(result -> assertTrue(result.getResolvedException() instanceof ResponseStatusException));

    }

Below is the stack trace of the error

java.lang.AssertionError: Status expected:<400> but was:<404>
    at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:59)
    at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:122)
    at org.springframework.test.web.servlet.result.StatusResultMatchers.lambda$matcher$9(StatusResultMatchers.java:627)
    at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:212)

Can someone help me with what I missed?
Thank you for your time.

Body:
By defining @GetMapping("/status/{uuid}"), you've defined an endpoint that requires an additional path. In the tests, however, the resulting URL is /status/ which does not match the pattern of the GetMapping hence the 404.

If you modify the GetMapping to also handle URIs without the additional path, it should trigger that method.

@GetMapping(value = {"/status", "/status/{uuid}"})
public ResponseEntity<StatusResponse> getStatusByUUID(@PathVariable(value = "uuid", required = false) String uuid) { ... }

Here was the test code I ran

@RestController
public class MyController {
  @GetMapping("/foo/{var}")
  public ResponseEntity<Void> foo(@PathVariable(value = "var") String var) {
    HttpStatus status = StringUtils.hasText(var) ? HttpStatus.OK : HttpStatus.BAD_REQUEST;
    return ResponseEntity.status(status).build();
  }

  @GetMapping(value = {"/bar", "/bar/{var}"})
  public ResponseEntity<Void> bar(@PathVariable(value = "var", required = false) String var) {
    HttpStatus status = StringUtils.hasText(var) ? HttpStatus.OK : HttpStatus.BAD_REQUEST;
    return ResponseEntity.status(status).build();
  }
}

public class MyTest {
  MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new MyController()).build();

  @Test
  public void foo() {
    MvcResult result = mockMvc.perform(get("/foo/{var}", "")).andReturn();
    assertEquals(404, result.getResponse.getStatus());
  }

  @Test
  public void bar1() {
    MvcResult result = mockMvc.perform(get("/bar/{var}", "val")).andReturn();
    assertEquals(200, result.getResponse.getStatus());
  }

  @Test
  public void bar2() {
    MvcResult result = mockMvc.perform(get("/bar/{var}", "")).andReturn();
    assertEquals(400, result.getResponse.getStatus());
  }
}


来源: stackexchange

问:
Recursive division over a list
I'm looking to divide every element of an list recursivly like this.

a_list = [1, 2, 3, 4, 5]
so the returns would be 1/(2/(3/(4/5)))

```<code>def c(y):

    if not y:
        return 1  # division by 1 don't matter

    return c(y[1:])[0] / c(y[2:])[1]  # Not allowed
</code>```

答:
Recursively, you can divide the first element by the result of recursing with the rest:

```<code>def recDiv(a):
    return a[0] / recDiv(a[1:]) if a else 1

a_list = [1, 2, 3, 4, 5]

print(recDiv(a_list)) # 1.875
</code>```

Alternatively you could use the prod() function from math and apply a power of 1 or -1 depending on items being at even or odd positions.

```<code>a_list = [1, 2, 3, 4, 5]

from math import prod

result = prod(n**[1,-1][i&1] for i,n in enumerate(a_list))

print(result) # 1.875
</code>```

Which would translate into a regular loop like this:

```<code>result = 1
for i,n in enumerate(a_list):
    result *= n ** [1,-1][i&1]  # result *= 1/n if i%2 else n

print(result) # 1.875
</code>```

ContentLicense: CC BY-SA 4.0

Title: Recursive division over a list

Body:
I'm looking to divide every element of an list recursivly like this.

a_list = [1, 2, 3, 4, 5]
so the returns would be 1/(2/(3/(4/5)))

def c(y):

    if not y:
        return 1  # division by 1 don't matter

    return c(y[1:])[0] / c(y[2:])[1]  # Not allowed

Body:
Recursively, you can divide the first element by the result of recursing with the rest:

def recDiv(a):
    return a[0] / recDiv(a[1:]) if a else 1

a_list = [1, 2, 3, 4, 5]

print(recDiv(a_list)) # 1.875

Alternatively you could use the prod() function from math and apply a power of 1 or -1 depending on items being at even or odd positions.

a_list = [1, 2, 3, 4, 5]

from math import prod

result = prod(n**[1,-1][i&1] for i,n in enumerate(a_list))

print(result) # 1.875

Which would translate into a regular loop like this:

result = 1
for i,n in enumerate(a_list):
    result *= n ** [1,-1][i&1]  # result *= 1/n if i%2 else n

print(result) # 1.875


问:
Alternative to $MyInvocation
When deploying PowerShell scripts from my RMM (NinjaOne), the scripts are called from a .bat (batch file).

Example:

@powershell -ExecutionPolicy Bypass -File "test.ps1" -stringParam "testing" -switchParam > "output.txt" 2>&1
```
<p>The script I am calling requires PowerShell 7+, so I need to restart the script by calling <code>pwsh</code> with the current parameters. I planned to accomplish this via the following:</p>
<pre class="lang-ps prettyprint-override"><code>Invoke-Command { & pwsh -Command $MyInvocation.Line } -NoNewScope
</code>```

Unfortunately, $MyInvocation.Line does not return the correct result when a PowerShell script is called from a batch file. What alternatives exist that would work in this scenario?

Notes:

I am unable to make changes to the .bat file.

$PSBoundParameters also does not return the expected result.

Testing Script (called from batch):

```<code>Param(
  [string]$string,
  [switch]$switch
)

if (!($PSVersionTable.PSVersion.Major -ge 7)) {
  Write-Output "`n"
  Write-Output 'Attempting to restart in PowerShell 7'
  if(!$MyInvocation.Line) {
    Write-Output 'Parameters not carried over - cannot restart'
    Exit
  } else { Write-Output $MyInvocation.Line }
  Invoke-Command { & pwsh -Command $MyInvocation.Line } -NoNewScope # PowerShell 7
  Exit
}

Write-Output 'Parameters carried over:'
Write-Output $PSBoundParameters

Write-Output "`nSuccessfully restarted"

</code>```

Edit: I've discovered the reason for $MyInvocation / $PSBoundParameters not being set properly is due to the use of -File instead of -Command when my RMM provider calls the PowerShell script from the .bat file. I've suggested they implement this change to resolve the issue. Until they do, I am still looking for alternatives.

答:
Leaving RMM providers out of the picture (whose involvement may or may not matter), the following test.ps1 content should work:

```<code># Note: Place [CmdletBinding()] above param(...) to make
#       the script an *advanced* one, which then prevents passing
#       extra arguments that don't bind to declared parameters.
param(
  [string] $stringParam,
  [switch] $switchParam
)

# If invoked via powershell.exe, re-invoke via pwsh.exe
if ((Get-Process -Id $PID).Name -eq 'powershell') {
   # $PSCommandPath is the current script's full file path,
   # and @PSBoundParameters uses splatting to pass all
   # arguments that were bound to declared parameters through.
   # Any extra arguments, if present, are passed through with @args
   pwsh -ExecutionPolicy Bypass -File $PSCommandPath @PSBoundParameters @args
   exit $LASTEXITCODE
}

# Getting here means that the file is being executed by pwsh.exe

# Print the arguments received:

if ($PSBoundParameters.Count) {
  "-- Bound parameters and their values:`n"
  # !! Because $PSBoundParameters causes table-formatted
  # !! output, synchronous output must be forced to work around a bug.
  # !! See notes below.
  $PSBoundParameters | Out-Host
}

if ($args) {
  "`n-- Unbound (positional) arguments:`n"
  $args
}

exit 0
</code>```

As suggested in the code comments, place [CmdletBinding()] above the param(...) block in order to make the script an advanced one, in which case passing extra arguments (ones that don't bind to formally declared parameters) is actively prevented (and in which case $args isn't defined).

Caveat:

Note the need for piping $PSBoundParameters to Out-Host in order to force synchronous output of the (default) table-formatted representation of its value. The same would apply to outputting any other values that would result in implicit Format-Table formatting not based on predefined formatting data ($args, as an array whose elements are strings isn't affected). (Note that While Out-Host output normally isn't suitable for data output from inside  a PowerShell session, it does write to an outside caller's stdout.)

This need stems from a very unfortunate output-timing bug, present in both Windows PowerShell and the current PowerShell (Core) version, 7.2.1; it is a variant manifestation of the behavior in detail in this answer and reported in GitHub issue #13985 and applies here because exit is called within 300 msecs. of initiating the implicitly table-formatted output; if you were to omit the final exit 0 statement, the problem wouldn't arise.

See also:

The automatic $PSCommandPath variable, reflecting the running script's full (absolute) path.

The automatic $PSBoundParameters variable, a dictionary containing all bound parameters and their values (arguments), and the automatic $args variable, containing all (remaining) positional arguments not bound to formally declared parameters.

Parameter splatting, in which referencing a hashtable (dictionary) or array variable with sigil @ instead of $, passes the hashtable's entries / array's elements as individual arguments.

powershell.exe, the Windows PowerShell CLI; pwsh, the PowerShell (Core) 7+ CLI.

Other automatic variables used above, namely $PID (the current process' ID) and $LASTEXITCODE (the most recently executed external program's exit code).

As for what you tried:

$MyInvocation.Line isn't defined when a script is called via PowerShell's CLI; however, the automatic $PSCommandPath variable, reflecting the running script's full file path, is defined.

Even if $MyInvocation.Line were defined, it wouldn't enable robust pass-through of the original arguments, due to potential quoting issues and - when called from inside PowerShell - due to reflecting unexpanded arguments. (Also, the value would start with the executable / script name / path, which would have to be removed.)

While [Environment]::CommandLine does reflect the process command line of the CLI call (also starting with the executable name / path), the quoting issues apply there too.

Also, it is virtually pointless to use Invoke-Command for local invocations - see this answer.

Title: Alternative to $MyInvocation

Body:
When deploying PowerShell scripts from my RMM (NinjaOne), the scripts are called from a .bat (batch file).

Example:

@powershell -ExecutionPolicy Bypass -File "test.ps1" -stringParam "testing" -switchParam > "output.txt" 2>&1

The script I am calling requires PowerShell 7+, so I need to restart the script by calling pwsh with the current parameters. I planned to accomplish this via the following:

Invoke-Command { & pwsh -Command $MyInvocation.Line } -NoNewScope

Unfortunately, $MyInvocation.Line does not return the correct result when a PowerShell script is called from a batch file. What alternatives exist that would work in this scenario?

Notes:

I am unable to make changes to the .bat file.

$PSBoundParameters also does not return the expected result.

Testing Script (called from batch):

Param(
  [string]$string,
  [switch]$switch
)

if (!($PSVersionTable.PSVersion.Major -ge 7)) {
  Write-Output "`n"
  Write-Output 'Attempting to restart in PowerShell 7'
  if(!$MyInvocation.Line) {
    Write-Output 'Parameters not carried over - cannot restart'
    Exit
  } else { Write-Output $MyInvocation.Line }
  Invoke-Command { & pwsh -Command $MyInvocation.Line } -NoNewScope # PowerShell 7
  Exit
}

Write-Output 'Parameters carried over:'
Write-Output $PSBoundParameters

Write-Output "`nSuccessfully restarted"

Edit: I've discovered the reason for $MyInvocation / $PSBoundParameters not being set properly is due to the use of -File instead of -Command when my RMM provider calls the PowerShell script from the .bat file. I've suggested they implement this change to resolve the issue. Until they do, I am still looking for alternatives.

Body:
Leaving RMM providers out of the picture (whose involvement may or may not matter), the following test.ps1 content should work:

# Note: Place [CmdletBinding()] above param(...) to make
#       the script an *advanced* one, which then prevents passing
#       extra arguments that don't bind to declared parameters.
param(
  [string] $stringParam,
  [switch] $switchParam
)

# If invoked via powershell.exe, re-invoke via pwsh.exe
if ((Get-Process -Id $PID).Name -eq 'powershell') {
   # $PSCommandPath is the current script's full file path,
   # and @PSBoundParameters uses splatting to pass all
   # arguments that were bound to declared parameters through.
   # Any extra arguments, if present, are passed through with @args
   pwsh -ExecutionPolicy Bypass -File $PSCommandPath @PSBoundParameters @args
   exit $LASTEXITCODE
}

# Getting here means that the file is being executed by pwsh.exe

# Print the arguments received:

if ($PSBoundParameters.Count) {
  "-- Bound parameters and their values:`n"
  # !! Because $PSBoundParameters causes table-formatted
  # !! output, synchronous output must be forced to work around a bug.
  # !! See notes below.
  $PSBoundParameters | Out-Host
}

if ($args) {
  "`n-- Unbound (positional) arguments:`n"
  $args
}

exit 0

As suggested in the code comments, place [CmdletBinding()] above the param(...) block in order to make the script an advanced one, in which case passing extra arguments (ones that don't bind to formally declared parameters) is actively prevented (and in which case $args isn't defined).

Caveat:

Note the need for piping $PSBoundParameters to Out-Host in order to force synchronous output of the (default) table-formatted representation of its value. The same would apply to outputting any other values that would result in implicit Format-Table formatting not based on predefined formatting data ($args, as an array whose elements are strings isn't affected). (Note that While Out-Host output normally isn't suitable for data output from inside  a PowerShell session, it does write to an outside caller's stdout.)

This need stems from a very unfortunate output-timing bug, present in both Windows PowerShell and the current PowerShell (Core) version, 7.2.1; it is a variant manifestation of the behavior in detail in this answer and reported in GitHub issue #13985 and applies here because exit is called within 300 msecs. of initiating the implicitly table-formatted output; if you were to omit the final exit 0 statement, the problem wouldn't arise.

See also:

The automatic $PSCommandPath variable, reflecting the running script's full (absolute) path.

The automatic $PSBoundParameters variable, a dictionary containing all bound parameters and their values (arguments), and the automatic $args variable, containing all (remaining) positional arguments not bound to formally declared parameters.

Parameter splatting, in which referencing a hashtable (dictionary) or array variable with sigil @ instead of $, passes the hashtable's entries / array's elements as individual arguments.

powershell.exe, the Windows PowerShell CLI; pwsh, the PowerShell (Core) 7+ CLI.

Other automatic variables used above, namely $PID (the current process' ID) and $LASTEXITCODE (the most recently executed external program's exit code).

As for what you tried:

$MyInvocation.Line isn't defined when a script is called via PowerShell's CLI; however, the automatic $PSCommandPath variable, reflecting the running script's full file path, is defined.

Even if $MyInvocation.Line were defined, it wouldn't enable robust pass-through of the original arguments, due to potential quoting issues and - when called from inside PowerShell - due to reflecting unexpanded arguments. (Also, the value would start with the executable / script name / path, which would have to be removed.)

While [Environment]::CommandLine does reflect the process command line of the CLI call (also starting with the executable name / path), the quoting issues apply there too.

Also, it is virtually pointless to use Invoke-Command for local invocations - see this answer.


问:
How can I set static Egress IP for a pod?
Shortly, there are two services that communicates with each others via HTTP REST APIs. My deployment is running in an AKS cluster. For ingress controller, I installed this Nginx controller helm chart:
https://kubernetes.github.io/ingress-nginx

The load balancer has a fix IP attached. My deployment running in my cluster should send usage info to the other service periodically and vica versa. However, that service has an IP whitelist and I need to provide a static IP for whitelisting my deployment. Currently, the problem is that my cURL call has the node's IP which is always changing depending on which node my deployment is running on. Also, the number of nodes are scaled dinamically, too. My goal is to send egress traffic through the loadbalancer something like this:

Is there any way to route the outbound traffic from my pods to the loadbalancer?

答: This is possible with Azure Load Balancer with outbound rules; which the LB will do a SNAT and your "other service" will see the fixed frontend public IP. Another method is use Virtual Network NAT where your "other service" will see the fixed NAT public IP. You can then whitelist the fixed public IP either way.</p>


问:
How to use read_csv to read .gz file with sep='\' in python3?
I would like to read some gz files by pandas, in which data are split by '', in python 3.

If I use the code:

```<code>pd.read_csv('my file.gz',sep='\')
</code>```

I will get the error "EOL while scanning string literal".

What is the correct way to do this?

答:
pd.read_csv('my file.gz',sep='\\') # use \\ instead of \
```

Sometimes csv file uses a specific separator, such as \t (TAB), instead of a comma(,). In this case, if the csv file use \ as a separator, you have to use \\ instead of \ because \ is an escape character.

There are many other special characters that require escape character \, such as \t (TAB), \\ (BACKSLASH), and \ (Single Quote).

You can see more information about ESCAPE here: https://www.w3schools.com/python/gloss_python_escape_characters.asp

Body:
I would like to read some gz files by pandas, in which data are split by '', in python 3.

If I use the code:

pd.read_csv('my file.gz',sep='\')

I will get the error "EOL while scanning string literal".

What is the correct way to do this?

Body:
pd.read_csv('my file.gz',sep='\\') # use \\ instead of \

Sometimes csv file uses a specific separator, such as \t (TAB), instead of a comma(,). In this case, if the csv file use \ as a separator, you have to use \\ instead of \ because \ is an escape character.

There are many other special characters that require escape character \, such as \t (TAB), \\ (BACKSLASH), and \ (Single Quote).

You can see more information about ESCAPE here: https://www.w3schools.com/python/gloss_python_escape_characters.asp


问:
Downloading Images from list of URL to server using PHP
I made a simple script that can download image from the URL. It perfectly works.

```<code>$img_link = 'https://samplesite.com/image.jpg';
$imge_title = basename($img_link);

$ch = curl_init($img_link);
$fp = fopen("folder/".$imge_title, 'wb');
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
fclose($fp);
?>
</code>```

The next thing to is to Download a list of URLS from a txt file and process them per line.

```<code>https://samplesite.com/image_1.jpg
https://samplesite.com/image_2.jpg
https://samplesite.com/image_3.jpg
https://samplesite.com/image_4.jpg
https://samplesite.com/image_5.jpg
</code>```

Here's what I came up with:

```<code>$lines = file( 'List.txt' ); //the list of image URLs

foreach ( $lines as $line ) {
$img_link = $line;
$imge_title = basename($img_link); //I want to retain the original name of the file

$ch = curl_init($img_link);
$fp = fopen($imge_title, 'wb');
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
fclose($fp);
}
</code>```

It doesn't work and I keep getting Warnings:

```<code>Warning: fopen(image_1.jpg): failed to open stream: No such file or directory
Warning: curl_setopt(): supplied argument is not a valid File-Handle resource
Warning: fclose() expects parameter 1 to be resource
</code>```

答:
As the file doc says, the file's newlines are preserved in the resulting array:

Each element of the array corresponds to a line in the file, with the newline still attached.

Pass the FILE_IGNORE_NEW_LINES flag to the file(...) call.

Otherwise, most or all of your $line values will end with a '\n' or '\r' character.

You should probably also pass FILE_SKIP_EMPTY_LINES.

$lines = file( 'List.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES ); //the list of image URLs
```

Body:
I made a simple script that can download image from the URL. It perfectly works.

$img_link = 'https://samplesite.com/image.jpg';
$imge_title = basename($img_link);

$ch = curl_init($img_link);
$fp = fopen("folder/".$imge_title, 'wb');
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
fclose($fp);
?>

The next thing to is to Download a list of URLS from a txt file and process them per line.

https://samplesite.com/image_1.jpg
https://samplesite.com/image_2.jpg
https://samplesite.com/image_3.jpg
https://samplesite.com/image_4.jpg
https://samplesite.com/image_5.jpg

Here's what I came up with:

$lines = file( 'List.txt' ); //the list of image URLs

foreach ( $lines as $line ) {
$img_link = $line;
$imge_title = basename($img_link); //I want to retain the original name of the file

$ch = curl_init($img_link);
$fp = fopen($imge_title, 'wb');
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
fclose($fp);
}

It doesn't work and I keep getting Warnings:

Warning: fopen(image_1.jpg): failed to open stream: No such file or directory
Warning: curl_setopt(): supplied argument is not a valid File-Handle resource
Warning: fclose() expects parameter 1 to be resource


问:
Excel VBA Searching Through a Large Array
I have an array of ~5,000 unique IDs loaded from a CSV file:

```<code>Dim wb As Workbook
Dim idRng As Variant

Set wb = Workbooks.Open(Filename:=ThisWorkbook.path & "\DataSource\ID.csv")

With wb.Sheets(1)
    idRng = .Range("A2:A" & .Range("A" & .Rows.Count).End(xlUp).Row).Value2
End With

wb.Close
</code>```

Alongside this, I also load in ~100,000 rows of data, which contains non-unique IDs with numerous possible duplicates.  My aim is to loop through the 100,000 rows and check if the corresponding rows ID is contained within the smaller array, and if so, add the rows data to a collection.  Both IDs are stored as Longs.  I have completed this using the below:

```<code>Dim dataRng As Variant
Set wb = Workbooks.Open(Filename:=ThisWorkbook.path & "\DataSource\data.csv")

With wb.Sheets(1)
    dataRng = .Range("A2:H" & .Range("A" & .Rows.Count).End(xlUp).Row).Value2

    For i = LBound(dataRng) To UBound(dataRng)
        If mUtil.IsInArray(dataRng(i, 1), idRng) Then
            'Add object to collection
        End If
    Next
End With

'mUtil
Public Function IsInArray(v As Variant, arr As Variant) As Boolean
    For i = LBound(arr) To UBound(arr)
        If arr(i, 1) = v Then
            IsInArray = True
            Exit Function
        End If
    Next

    IsInArray = False
End Function
</code>```

Despite this working, as you can imagine iterating through the 5,000 unique IDs 100,000 times can take a fair amount of time, alongside this, the larger file can end up being much bigger.

Is there a more efficient way of performing this task, with the ultimate aim to reduce the run time?

答:
I'd suggest throwing your 5,000 records into a dictionary and then use the Exists method to check to see if it does in fact exist.

```<code>Public Sub DictionaryTest()
    Dim lngKey As Long, objDict As Object

    Set objDict = CreateObject("Scripting.Dictionary")

    lngKey = 123456

    objDict.Add lngKey, 0

    Debug.Print objDict.Exists(lngKey)
End Sub
</code>```

It absolves you from having to loop over the 5,000 each time AND the power of the search within the dictionary should speed up the process 10 fold.

Body:
I have an array of ~5,000 unique IDs loaded from a CSV file:

Dim wb As Workbook
Dim idRng As Variant

Set wb = Workbooks.Open(Filename:=ThisWorkbook.path & "\DataSource\ID.csv")

With wb.Sheets(1)
    idRng = .Range("A2:A" & .Range("A" & .Rows.Count).End(xlUp).Row).Value2
End With

wb.Close

Alongside this, I also load in ~100,000 rows of data, which contains non-unique IDs with numerous possible duplicates.  My aim is to loop through the 100,000 rows and check if the corresponding rows ID is contained within the smaller array, and if so, add the rows data to a collection.  Both IDs are stored as Longs.  I have completed this using the below:

Dim dataRng As Variant
Set wb = Workbooks.Open(Filename:=ThisWorkbook.path & "\DataSource\data.csv")

With wb.Sheets(1)
    dataRng = .Range("A2:H" & .Range("A" & .Rows.Count).End(xlUp).Row).Value2

    For i = LBound(dataRng) To UBound(dataRng)
        If mUtil.IsInArray(dataRng(i, 1), idRng) Then
            'Add object to collection
        End If
    Next
End With

'mUtil
Public Function IsInArray(v As Variant, arr As Variant) As Boolean
    For i = LBound(arr) To UBound(arr)
        If arr(i, 1) = v Then
            IsInArray = True
            Exit Function
        End If
    Next

    IsInArray = False
End Function

Despite this working, as you can imagine iterating through the 5,000 unique IDs 100,000 times can take a fair amount of time, alongside this, the larger file can end up being much bigger.

Is there a more efficient way of performing this task, with the ultimate aim to reduce the run time?

Body:
I'd suggest throwing your 5,000 records into a dictionary and then use the Exists method to check to see if it does in fact exist.

Public Sub DictionaryTest()
    Dim lngKey As Long, objDict As Object

    Set objDict = CreateObject("Scripting.Dictionary")

    lngKey = 123456

    objDict.Add lngKey, 0

    Debug.Print objDict.Exists(lngKey)
End Sub

It absolves you from having to loop over the 5,000 each time AND the power of the search within the dictionary should speed up the process 10 fold.


问:
How do I put a conditional and a loop in the same line?
I would like to put a conditional and loop on the same line on Perl. This is what I would like to achieve:

```<code>foreach (0 .. 10) {
    print $_ if $_ % 2;
}
</code>```

which should give me 13579. I'm looking for a statement like loop comprehension in Python, e.g.

```<code>[i for i in range(10) if i % 2]
</code>```

I know that print $_ foreach 0 .. 10; works but the problem is adding the conditional to the statement as well...

答:
Perl isn't Python.  List comprehensions are nice, but Perl doesn't have them.

The closest perl idiom is probably something like

```<code>grep $_ % 2 , (0..9);
</code>```

A 1-liner to try it out:

```<code>$ perl -e '@a = grep $_ % 2 , (0..9); print "@a\n"'
1 3 5 7 9
</code>```

Note there's probably a performance difference in both memory and time. I'm pretty sure Perl will build the complete list of 10 items and filter it to make a new list. The list comprehension can build the filtered list directly.

Body:
I would like to put a conditional and loop on the same line on Perl. This is what I would like to achieve:

foreach (0 .. 10) {
    print $_ if $_ % 2;
}

which should give me 13579. I'm looking for a statement like loop comprehension in Python, e.g.

[i for i in range(10) if i % 2]

I know that print $_ foreach 0 .. 10; works but the problem is adding the conditional to the statement as well...

Body:
Perl isn't Python.  List comprehensions are nice, but Perl doesn't have them.

The closest perl idiom is probably something like

grep $_ % 2 , (0..9);

A 1-liner to try it out:

$ perl -e '@a = grep $_ % 2 , (0..9); print "@a\n"'
1 3 5 7 9

Note there's probably a performance difference in both memory and time. I'm pretty sure Perl will build the complete list of 10 items and filter it to make a new list. The list comprehension can build the filtered list directly.


问:
How to get all results from multiple columns in a single column - SQL?
I want to get all the results in 2 of my columns together.

I have a table my_table like:

```<code>colA    colB
a       e
b       e
c       f
d       g
</code>```

Intended output:

```<code>id      letter
1       a
2       b
3       c
4       d
5       e
6       f
7       g
</code>```

I know this is achievable with UNION but I'm a bit confused about how the numbering would work then. I'm good with a solution without UNION too. The order of letter in the output also doesn't matter, but each value needs a unique ID.

What I tried:

```<code>SELECT
     row_number() OVER (ORDER BY letter) AS id,
     colA AS letter
FROM my_table
UNION
SELECT
     row_number() OVER (ORDER BY letter) AS id,
     colB AS letter
FROM my_table
</code>```

答:
```<code>SELECT row_number() OVER (ORDER BY letter) AS id, *
FROM (
     SELECT DISTINCT colA AS letter
     FROM my_table
     UNION
     SELECT DISTINCT colB AS letter
     FROM my_table
)
</code>```

Body:
I want to get all the results in 2 of my columns together.

I have a table my_table like:

colA    colB
a       e
b       e
c       f
d       g

Intended output:

id      letter
1       a
2       b
3       c
4       d
5       e
6       f
7       g

I know this is achievable with UNION but I'm a bit confused about how the numbering would work then. I'm good with a solution without UNION too. The order of letter in the output also doesn't matter, but each value needs a unique ID.

What I tried:

SELECT
     row_number() OVER (ORDER BY letter) AS id,
     colA AS letter
FROM my_table
UNION
SELECT
     row_number() OVER (ORDER BY letter) AS id,
     colB AS letter
FROM my_table


答:
You can try something as simple as the following. Instead of looping twice, just loop one of them and Match if the item is found in the other array. I just tested with random numbers and just looped the unique values. This would work only if you want the first match. If you want all the matches you need to simply reverse it and loop the 100k non-unique array to the unique one.
What we do is create MatchArr as a Variant and then use that variable for our Application.Match function. If the function finds a match, it returns the row it found it on. If it doesn't find a match it will error, but because we made it a variant it won't stop the code. We simply check if it's an error or not and if it is then we simply move to the next line.

This is what I tried (Change as needed):

EDIT: I've updated to do the loop of the bigger array that needs to be refined.

```<code>Sub FindValues()

Dim Arr1, Arr2, MatchArr, i As Long, Col As New Collection

Arr1 = Sheet1.Range("A1:A50").Value
Arr2 = Sheet1.Range("C1:C1000").Value

For i = LBound(Arr2, 1) To UBound(Arr2, 1)
    MatchArr = Application.Match(Arr2(i, 1), Arr1, 0)
    If Not IsError(MatchArr) Then
        Col.Add Arr2(i, 1)
    End If
Next i

For i = 1 To Col.Count
    Sheet1.Range("E" & i).Value = Col(i)
Next i

End Sub
</code>```

Title: Excel VBA Searching Through a Large Array

Body:
You can try something as simple as the following. Instead of looping twice, just loop one of them and Match if the item is found in the other array. I just tested with random numbers and just looped the unique values. This would work only if you want the first match. If you want all the matches you need to simply reverse it and loop the 100k non-unique array to the unique one.
What we do is create MatchArr as a Variant and then use that variable for our Application.Match function. If the function finds a match, it returns the row it found it on. If it doesn't find a match it will error, but because we made it a variant it won't stop the code. We simply check if it's an error or not and if it is then we simply move to the next line.

This is what I tried (Change as needed):

EDIT: I've updated to do the loop of the bigger array that needs to be refined.

Sub FindValues()

Dim Arr1, Arr2, MatchArr, i As Long, Col As New Collection

Arr1 = Sheet1.Range("A1:A50").Value
Arr2 = Sheet1.Range("C1:C1000").Value

For i = LBound(Arr2, 1) To UBound(Arr2, 1)
    MatchArr = Application.Match(Arr2(i, 1), Arr1, 0)
    If Not IsError(MatchArr) Then
        Col.Add Arr2(i, 1)
    End If
Next i

For i = 1 To Col.Count
    Sheet1.Range("E" & i).Value = Col(i)
Next i

End Sub


答:
I put this line in test.ps1:

```<code>$MyInvocation | Format-List -Property *
</code>```

Found this content in output.txt:

```<code>

MyCommand             : test.ps1
BoundParameters       : {}
UnboundArguments      : {-stringParam, testing, -switchParam}
ScriptLineNumber      : 0
OffsetInLine          : 0
HistoryId             : 1
ScriptName            :
Line                  :
PositionMessage       :
PSScriptRoot          :
PSCommandPath         :
InvocationName        : D:\Temp\StackOverflow\71087897\test.ps1
PipelineLength        : 2
PipelinePosition      : 1
ExpectingInput        : False
CommandOrigin         : Runspace
DisplayScriptPosition :

</code>```

Then tried this in test.ps1:

```<code>[string]$MySelf = $MyInvocation.InvocationName
Write-Host "###$MySelf###"
[string[]]$Params = $MyInvocation.UnboundArguments
foreach ($Param in $Params) {
    Write-Host "Param: '$Param'"
}
</code>```

And found this in output.txt:

```<code>###D:\Temp\StackOverflow\71087897\test.ps1###
Param: '-stringParam'
Param: 'testing'
Param: '-switchParam'
</code>```

Then tried this in test.ps1:

```<code>[string]$Line = "$($MyInvocation.InvocationName) $($MyInvocation.UnboundArguments)"
Write-Host "$Line"
</code>```

And found this in output.txt:

```<code>D:\Temp\StackOverflow\71087897\test.ps1 -stringParam testing -switchParam
</code>```

Does this get you to where you need to be?

Title: Alternative to $MyInvocation

Body:
I put this line in test.ps1:

$MyInvocation | Format-List -Property *

Found this content in output.txt:

MyCommand             : test.ps1
BoundParameters       : {}
UnboundArguments      : {-stringParam, testing, -switchParam}
ScriptLineNumber      : 0
OffsetInLine          : 0
HistoryId             : 1
ScriptName            :
Line                  :
PositionMessage       :
PSScriptRoot          :
PSCommandPath         :
InvocationName        : D:\Temp\StackOverflow\71087897\test.ps1
PipelineLength        : 2
PipelinePosition      : 1
ExpectingInput        : False
CommandOrigin         : Runspace
DisplayScriptPosition :

Then tried this in test.ps1:

[string]$MySelf = $MyInvocation.InvocationName
Write-Host "###$MySelf###"
[string[]]$Params = $MyInvocation.UnboundArguments
foreach ($Param in $Params) {
    Write-Host "Param: '$Param'"
}

And found this in output.txt:

###D:\Temp\StackOverflow\71087897\test.ps1###
Param: '-stringParam'
Param: 'testing'
Param: '-switchParam'

Then tried this in test.ps1:

[string]$Line = "$($MyInvocation.InvocationName) $($MyInvocation.UnboundArguments)"
Write-Host "$Line"

And found this in output.txt:

D:\Temp\StackOverflow\71087897\test.ps1 -stringParam testing -switchParam

Does this get you to where you need to be?


问:
Why am I getting Access denied in my namecheap nodejs app?
I created a Simple API using NodeJS, Express and MariaDB, to test database connection issues I've been having. This works fine locally, but not on NameCheap servers.
This is the error I get:

```<code>(conn=18541114, no: 1045, SQLState: 28000) Access denied for user 'madejnsw_demouser'@'localhost' (using password: YES)
</code>```

error logs:

```<code>    at Object.module.exports.createError (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/misc/errors.js:61:10)
    at Handshake.throwError (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/cmd/command.js:82:22)
    at Handshake.handshakeResult (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/cmd/handshake/handshake.js:131:28)
    at PacketInputStream.receivePacketBasic (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/io/packet-input-stream.js:104:9)
    at PacketInputStream.onData (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/io/packet-input-stream.js:169:20)
    at Socket.emit (events.js:314:20)
    at addChunk (_stream_readable.js:297:12)
    at readableAddChunk (_stream_readable.js:272:9)
    at Socket.Readable.push (_stream_readable.js:213:10)
    at TCP.onStreamRead (internal/stream_base_commons.js:188:23)
 From event:
    at _registerHandshakeCmd (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/connection.js:745:11)
    at /home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/connection.js:57:11
    at new Promise (<anonymous>)
    at Connection.connect (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/connection.js:56:16)
    at createConnectionPoolPromise (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-promise.js:31:8)
    at creationTryout (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:373:9)
    at /home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:392:7
    at new Promise (<anonymous>)
    at connectionCreationLoop (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:356:12)
    at PoolPromise.PoolBase.initialize (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:142:5)
(node:2798261) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 3)
(node:2798261) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
(node:2806739) UnhandledPromiseRejectionWarning: Error: (conn=17370601, no: 1045, SQLState: 28000) Access denied for user 'madejnsw_demouser'@'localhost' (using password: YES)
    at Object.module.exports.createError (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/misc/errors.js:61:10)
    at Handshake.throwError (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/cmd/command.js:82:22)
    at Handshake.handshakeResult (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/cmd/handshake/handshake.js:131:28)
    at PacketInputStream.receivePacketBasic (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/io/packet-input-stream.js:104:9)
    at PacketInputStream.onData (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/io/packet-input-stream.js:169:20)
    at Socket.emit (events.js:314:20)
    at addChunk (_stream_readable.js:297:12)
    at readableAddChunk (_stream_readable.js:272:9)
    at Socket.Readable.push (_stream_readable.js:213:10)
    at TCP.onStreamRead (internal/stream_base_commons.js:188:23)
 From event:
    at _registerHandshakeCmd (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/connection.js:745:11)
    at /home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/connection.js:57:11
    at new Promise (<anonymous>)
    at Connection.connect (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/connection.js:56:16)
    at createConnectionPoolPromise (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-promise.js:31:8)
    at creationTryout (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:373:9)
    at /home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:392:7
    at new Promise (<anonymous>)
    at connectionCreationLoop (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:356:12)
    at PoolPromise.PoolBase.initialize (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:142:5)
(node:2806739) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 3)
(node:2806739) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
(node:2807107) UnhandledPromiseRejectionWarning: Error: (conn=17370830, no: 1045, SQLState: 28000) Access denied for user 'madejnsw_demouser'@'localhost' (using password: YES)
    at Object.module.exports.createError (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/misc/errors.js:61:10)
    at Handshake.throwError (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/cmd/command.js:82:22)
    at Handshake.handshakeResult (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/cmd/handshake/handshake.js:131:28)
    at PacketInputStream.receivePacketBasic (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/io/packet-input-stream.js:104:9)
    at PacketInputStream.onData (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/io/packet-input-stream.js:169:20)
    at Socket.emit (events.js:314:20)
    at addChunk (_stream_readable.js:297:12)
    at readableAddChunk (_stream_readable.js:272:9)
    at Socket.Readable.push (_stream_readable.js:213:10)
    at TCP.onStreamRead (internal/stream_base_commons.js:188:23)
 From event:
    at _registerHandshakeCmd (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/connection.js:745:11)
    at /home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/connection.js:57:11
    at new Promise (<anonymous>)
    at Connection.connect (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/connection.js:56:16)
    at createConnectionPoolPromise (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-promise.js:31:8)
    at creationTryout (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:373:9)
    at /home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:392:7
    at new Promise (<anonymous>)
    at connectionCreationLoop (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:356:12)
    at PoolPromise.PoolBase.initialize (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:142:5)
(node:2807107) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 4)
(node:2807107) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
(node:2813149) UnhandledPromiseRejectionWarning: Error: (conn=17375021, no: 1045, SQLState: 28000) Access denied for user 'madejnsw_demouser'@'localhost' (using password: YES)
    at Object.module.exports.createError (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/misc/errors.js:61:10)
    at Handshake.throwError (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/cmd/command.js:82:22)
    at Handshake.handshakeResult (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/cmd/handshake/handshake.js:131:28)
    at PacketInputStream.receivePacketBasic (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/io/packet-input-stream.js:104:9)
    at PacketInputStream.onData (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/io/packet-input-stream.js:169:20)
    at Socket.emit (events.js:314:20)
    at addChunk (_stream_readable.js:297:12)
    at readableAddChunk (_stream_readable.js:272:9)
    at Socket.Readable.push (_stream_readable.js:213:10)
    at TCP.onStreamRead (internal/stream_base_commons.js:188:23)
 From event:
    at _registerHandshakeCmd (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/connection.js:745:11)
    at /home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/connection.js:57:11
    at new Promise (<anonymous>)
    at Connection.connect (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/connection.js:56:16)
    at createConnectionPoolPromise (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-promise.js:31:8)
    at creationTryout (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:373:9)
    at /home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:392:7
    at new Promise (<anonymous>)
    at connectionCreationLoop (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:356:12)
    at PoolPromise.PoolBase.initialize (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:142:5)
(node:2813149) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 4)
(node:2813149) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
(node:2817491) UnhandledPromiseRejectionWarning: Error: (conn=17377684, no: 1045, SQLState: 28000) Access denied for user 'madejnsw_demouser'@'localhost' (using password: YES)
    at Object.module.exports.createError (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/misc/errors.js:61:10)
    at Handshake.throwError (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/cmd/command.js:82:22)
    at Handshake.handshakeResult (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/cmd/handshake/handshake.js:131:28)
    at PacketInputStream.receivePacketBasic (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/io/packet-input-stream.js:104:9)
    at PacketInputStream.onData (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/io/packet-input-stream.js:169:20)
    at Socket.emit (events.js:314:20)
    at addChunk (_stream_readable.js:297:12)
    at readableAddChunk (_stream_readable.js:272:9)
    at Socket.Readable.push (_stream_readable.js:213:10)
    at TCP.onStreamRead (internal/stream_base_commons.js:188:23)
 From event:
    at _registerHandshakeCmd (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/connection.js:745:11)
    at /home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/connection.js:57:11
    at new Promise (<anonymous>)
    at Connection.connect (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/connection.js:56:16)
    at createConnectionPoolPromise (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-promise.js:31:8)
    at creationTryout (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:373:9)
    at /home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:392:7
    at new Promise (<anonymous>)
    at connectionCreationLoop (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:356:12)
    at PoolPromise.PoolBase.initialize (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:142:5)
(node:2817491) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 4)
(node:2817491) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
(node:3226965) UnhandledPromiseRejectionWarning: Error: (conn=17531002, no: 1045, SQLState: 28000) Access denied for user 'madejnsw_demouser'@'localhost' (using password: YES)
    at Object.module.exports.createError (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/misc/errors.js:61:10)
    at Handshake.throwError (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/cmd/command.js:82:22)
    at Handshake.handshakeResult (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/cmd/handshake/handshake.js:131:28)
    at PacketInputStream.receivePacketBasic (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/io/packet-input-stream.js:104:9)
    at PacketInputStream.onData (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/io/packet-input-stream.js:169:20)
    at Socket.emit (events.js:314:20)
    at addChunk (_stream_readable.js:297:12)
    at readableAddChunk (_stream_readable.js:272:9)
    at Socket.Readable.push (_stream_readable.js:213:10)
    at TCP.onStreamRead (internal/stream_base_commons.js:188:23)
 From event:
    at _registerHandshakeCmd (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/connection.js:745:11)
    at /home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/connection.js:57:11
    at new Promise (<anonymous>)
    at Connection.connect (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/connection.js:56:16)
    at createConnectionPoolPromise (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-promise.js:31:8)
    at creationTryout (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:373:9)
    at /home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:392:7
    at new Promise (<anonymous>)
    at connectionCreationLoop (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:356:12)
    at PoolPromise.PoolBase.initialize (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:142:5)
(node:3226965) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 3)
(node:3226965) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
</code>```

This is my simple server.js:

```<code>const express = require('express');
const dotenv = require('dotenv');

dotenv.config({path: '.env-local'});

const PORT = process.env.PORT || '3000';
const app = express();

const userRouter = require('./routes/user');

app.use(express.json());
app.use(express.urlencoded({extended:false}));

//routes
app.get('/', (req, res) => {
    res.status(200).send("this is not why you're here. Go to /user/:id and replace :id with your user id.");
});

//middleware
app.use('/user', userRouter);

//start listening
/*
app.listen(PORT, () => {
    console.log(`Listening on port ${PORT}`);
});
*/
app.listen();
</code>```

user.js

```<code>const express = require('express');
const router = express.Router();
const pool = require('../helpers/database');
const bcrypt = require('bcrypt');

router.get('/:id', async (req, res) => {
    try {
        const sqlQuery = 'SELECT id, email, password, created_at FROM user WHERE id=?';
        const rows = await pool.query(sqlQuery, req.params.id);
        res.status(200).json(rows);
    } catch (error) {
        res.status(400).send(error.message);
    }
    //res.status(200).json({id:req.params.id});
})

router.post('/register', async (req,res) => {
    try {
        const {email, password} = req.body;

        const encryptedPassword = await bcrypt.hash(password, 10);

        const sqlQuery = 'INSERT INTO user (email, password) VALUES (?,?)';
        const result = await pool.query(sqlQuery, [email, encryptedPassword]);

        res.status(200).json({userId: result.insertId});
    } catch (error) {
        res.status(400).send(error.message);
    }
});

module.exports = router;
</code>```

database.js:

```<code>const mariadb = require('mariadb');

const pool = mariadb.createPool({
    host: process.env.DB_HOST,
    user: process.env.DB_USER,
    password: process.env.DB_PASS,
    database: process.env.DB_NAME,
    connectionLimit: 5
})

//connect/check for errors
pool.getConnection((err, connection) => {
    if(err) {
        if (err.code === 'PROTOCOL_CONNECTION_LOST') {
            console.error('Database connection lost');
        }
        if (err.code === 'ER_CON_COUNT_ERROR') {
            console.error('Database has too many connection');
        }
        if (err.code === 'ECONNREFUSED') {
            console.error('Database connection was refused');
        }
    }
    console.log('yes connected!!: ', connection);
    if (connection) connection.release();

    return;
});

module.exports = pool;
</code>```

I've set Namecheap environment variables as well:

```<code>#PORT=3000
DB_HOST= localhost
DB_USER= madejnsw_demouser
DB_PASS= A(uGZY$Psx81
DB_NAME= madejnsw_demo_user
</code>```

user has all permissions as well, I can't figure this issue out with Namecheap, anyone been successful with launching a working nodejs app with a mariadb database on namecheap servers? I would appreciate any help here.
Thanks.

答: I recreated the database using Namecheap PhpMyAdmin, and support had to fix some terminal issues on their end.</p>

Body:
I created a Simple API using NodeJS, Express and MariaDB, to test database connection issues I've been having. This works fine locally, but not on NameCheap servers.
This is the error I get:

(conn=18541114, no: 1045, SQLState: 28000) Access denied for user 'madejnsw_demouser'@'localhost' (using password: YES)

error logs:

    at Object.module.exports.createError (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/misc/errors.js:61:10)
    at Handshake.throwError (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/cmd/command.js:82:22)
    at Handshake.handshakeResult (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/cmd/handshake/handshake.js:131:28)
    at PacketInputStream.receivePacketBasic (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/io/packet-input-stream.js:104:9)
    at PacketInputStream.onData (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/io/packet-input-stream.js:169:20)
    at Socket.emit (events.js:314:20)
    at addChunk (_stream_readable.js:297:12)
    at readableAddChunk (_stream_readable.js:272:9)
    at Socket.Readable.push (_stream_readable.js:213:10)
    at TCP.onStreamRead (internal/stream_base_commons.js:188:23)
 From event:
    at _registerHandshakeCmd (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/connection.js:745:11)
    at /home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/connection.js:57:11
    at new Promise (<anonymous>)
    at Connection.connect (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/connection.js:56:16)
    at createConnectionPoolPromise (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-promise.js:31:8)
    at creationTryout (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:373:9)
    at /home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:392:7
    at new Promise (<anonymous>)
    at connectionCreationLoop (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:356:12)
    at PoolPromise.PoolBase.initialize (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:142:5)
(node:2798261) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 3)
(node:2798261) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
(node:2806739) UnhandledPromiseRejectionWarning: Error: (conn=17370601, no: 1045, SQLState: 28000) Access denied for user 'madejnsw_demouser'@'localhost' (using password: YES)
    at Object.module.exports.createError (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/misc/errors.js:61:10)
    at Handshake.throwError (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/cmd/command.js:82:22)
    at Handshake.handshakeResult (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/cmd/handshake/handshake.js:131:28)
    at PacketInputStream.receivePacketBasic (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/io/packet-input-stream.js:104:9)
    at PacketInputStream.onData (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/io/packet-input-stream.js:169:20)
    at Socket.emit (events.js:314:20)
    at addChunk (_stream_readable.js:297:12)
    at readableAddChunk (_stream_readable.js:272:9)
    at Socket.Readable.push (_stream_readable.js:213:10)
    at TCP.onStreamRead (internal/stream_base_commons.js:188:23)
 From event:
    at _registerHandshakeCmd (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/connection.js:745:11)
    at /home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/connection.js:57:11
    at new Promise (<anonymous>)
    at Connection.connect (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/connection.js:56:16)
    at createConnectionPoolPromise (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-promise.js:31:8)
    at creationTryout (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:373:9)
    at /home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:392:7
    at new Promise (<anonymous>)
    at connectionCreationLoop (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:356:12)
    at PoolPromise.PoolBase.initialize (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:142:5)
(node:2806739) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 3)
(node:2806739) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
(node:2807107) UnhandledPromiseRejectionWarning: Error: (conn=17370830, no: 1045, SQLState: 28000) Access denied for user 'madejnsw_demouser'@'localhost' (using password: YES)
    at Object.module.exports.createError (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/misc/errors.js:61:10)
    at Handshake.throwError (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/cmd/command.js:82:22)
    at Handshake.handshakeResult (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/cmd/handshake/handshake.js:131:28)
    at PacketInputStream.receivePacketBasic (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/io/packet-input-stream.js:104:9)
    at PacketInputStream.onData (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/io/packet-input-stream.js:169:20)
    at Socket.emit (events.js:314:20)
    at addChunk (_stream_readable.js:297:12)
    at readableAddChunk (_stream_readable.js:272:9)
    at Socket.Readable.push (_stream_readable.js:213:10)
    at TCP.onStreamRead (internal/stream_base_commons.js:188:23)
 From event:
    at _registerHandshakeCmd (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/connection.js:745:11)
    at /home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/connection.js:57:11
    at new Promise (<anonymous>)
    at Connection.connect (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/connection.js:56:16)
    at createConnectionPoolPromise (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-promise.js:31:8)
    at creationTryout (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:373:9)
    at /home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:392:7
    at new Promise (<anonymous>)
    at connectionCreationLoop (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:356:12)
    at PoolPromise.PoolBase.initialize (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:142:5)
(node:2807107) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 4)
(node:2807107) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
(node:2813149) UnhandledPromiseRejectionWarning: Error: (conn=17375021, no: 1045, SQLState: 28000) Access denied for user 'madejnsw_demouser'@'localhost' (using password: YES)
    at Object.module.exports.createError (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/misc/errors.js:61:10)
    at Handshake.throwError (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/cmd/command.js:82:22)
    at Handshake.handshakeResult (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/cmd/handshake/handshake.js:131:28)
    at PacketInputStream.receivePacketBasic (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/io/packet-input-stream.js:104:9)
    at PacketInputStream.onData (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/io/packet-input-stream.js:169:20)
    at Socket.emit (events.js:314:20)
    at addChunk (_stream_readable.js:297:12)
    at readableAddChunk (_stream_readable.js:272:9)
    at Socket.Readable.push (_stream_readable.js:213:10)
    at TCP.onStreamRead (internal/stream_base_commons.js:188:23)
 From event:
    at _registerHandshakeCmd (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/connection.js:745:11)
    at /home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/connection.js:57:11
    at new Promise (<anonymous>)
    at Connection.connect (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/connection.js:56:16)
    at createConnectionPoolPromise (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-promise.js:31:8)
    at creationTryout (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:373:9)
    at /home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:392:7
    at new Promise (<anonymous>)
    at connectionCreationLoop (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:356:12)
    at PoolPromise.PoolBase.initialize (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:142:5)
(node:2813149) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 4)
(node:2813149) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
(node:2817491) UnhandledPromiseRejectionWarning: Error: (conn=17377684, no: 1045, SQLState: 28000) Access denied for user 'madejnsw_demouser'@'localhost' (using password: YES)
    at Object.module.exports.createError (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/misc/errors.js:61:10)
    at Handshake.throwError (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/cmd/command.js:82:22)
    at Handshake.handshakeResult (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/cmd/handshake/handshake.js:131:28)
    at PacketInputStream.receivePacketBasic (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/io/packet-input-stream.js:104:9)
    at PacketInputStream.onData (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/io/packet-input-stream.js:169:20)
    at Socket.emit (events.js:314:20)
    at addChunk (_stream_readable.js:297:12)
    at readableAddChunk (_stream_readable.js:272:9)
    at Socket.Readable.push (_stream_readable.js:213:10)
    at TCP.onStreamRead (internal/stream_base_commons.js:188:23)
 From event:
    at _registerHandshakeCmd (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/connection.js:745:11)
    at /home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/connection.js:57:11
    at new Promise (<anonymous>)
    at Connection.connect (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/connection.js:56:16)
    at createConnectionPoolPromise (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-promise.js:31:8)
    at creationTryout (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:373:9)
    at /home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:392:7
    at new Promise (<anonymous>)
    at connectionCreationLoop (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:356:12)
    at PoolPromise.PoolBase.initialize (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:142:5)
(node:2817491) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 4)
(node:2817491) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
(node:3226965) UnhandledPromiseRejectionWarning: Error: (conn=17531002, no: 1045, SQLState: 28000) Access denied for user 'madejnsw_demouser'@'localhost' (using password: YES)
    at Object.module.exports.createError (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/misc/errors.js:61:10)
    at Handshake.throwError (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/cmd/command.js:82:22)
    at Handshake.handshakeResult (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/cmd/handshake/handshake.js:131:28)
    at PacketInputStream.receivePacketBasic (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/io/packet-input-stream.js:104:9)
    at PacketInputStream.onData (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/io/packet-input-stream.js:169:20)
    at Socket.emit (events.js:314:20)
    at addChunk (_stream_readable.js:297:12)
    at readableAddChunk (_stream_readable.js:272:9)
    at Socket.Readable.push (_stream_readable.js:213:10)
    at TCP.onStreamRead (internal/stream_base_commons.js:188:23)
 From event:
    at _registerHandshakeCmd (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/connection.js:745:11)
    at /home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/connection.js:57:11
    at new Promise (<anonymous>)
    at Connection.connect (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/connection.js:56:16)
    at createConnectionPoolPromise (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-promise.js:31:8)
    at creationTryout (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:373:9)
    at /home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:392:7
    at new Promise (<anonymous>)
    at connectionCreationLoop (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:356:12)
    at PoolPromise.PoolBase.initialize (/home/madejnsw/nodevenv/SimpleAPI/12/lib/node_modules/mariadb/lib/pool-base.js:142:5)
(node:3226965) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 3)
(node:3226965) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

This is my simple server.js:

const express = require('express');
const dotenv = require('dotenv');

dotenv.config({path: '.env-local'});

const PORT = process.env.PORT || '3000';
const app = express();

const userRouter = require('./routes/user');

app.use(express.json());
app.use(express.urlencoded({extended:false}));

//routes
app.get('/', (req, res) => {
    res.status(200).send("this is not why you're here. Go to /user/:id and replace :id with your user id.");
});

//middleware
app.use('/user', userRouter);

//start listening
/*
app.listen(PORT, () => {
    console.log(`Listening on port ${PORT}`);
});
*/
app.listen();

user.js

const express = require('express');
const router = express.Router();
const pool = require('../helpers/database');
const bcrypt = require('bcrypt');

router.get('/:id', async (req, res) => {
    try {
        const sqlQuery = 'SELECT id, email, password, created_at FROM user WHERE id=?';
        const rows = await pool.query(sqlQuery, req.params.id);
        res.status(200).json(rows);
    } catch (error) {
        res.status(400).send(error.message);
    }
    //res.status(200).json({id:req.params.id});
})

router.post('/register', async (req,res) => {
    try {
        const {email, password} = req.body;

        const encryptedPassword = await bcrypt.hash(password, 10);

        const sqlQuery = 'INSERT INTO user (email, password) VALUES (?,?)';
        const result = await pool.query(sqlQuery, [email, encryptedPassword]);

        res.status(200).json({userId: result.insertId});
    } catch (error) {
        res.status(400).send(error.message);
    }
});

module.exports = router;

database.js:

const mariadb = require('mariadb');

const pool = mariadb.createPool({
    host: process.env.DB_HOST,
    user: process.env.DB_USER,
    password: process.env.DB_PASS,
    database: process.env.DB_NAME,
    connectionLimit: 5
})

//connect/check for errors
pool.getConnection((err, connection) => {
    if(err) {
        if (err.code === 'PROTOCOL_CONNECTION_LOST') {
            console.error('Database connection lost');
        }
        if (err.code === 'ER_CON_COUNT_ERROR') {
            console.error('Database has too many connection');
        }
        if (err.code === 'ECONNREFUSED') {
            console.error('Database connection was refused');
        }
    }
    console.log('yes connected!!: ', connection);
    if (connection) connection.release();

    return;
});

module.exports = pool;

I've set Namecheap environment variables as well:

#PORT=3000
DB_HOST= localhost
DB_USER= madejnsw_demouser
DB_PASS= A(uGZY$Psx81
DB_NAME= madejnsw_demo_user

user has all permissions as well, I can't figure this issue out with Namecheap, anyone been successful with launching a working nodejs app with a mariadb database on namecheap servers? I would appreciate any help here.
Thanks.


问:
SQL query to get certain matching rows
I was asked to write a query to return address for some customers in our system.

Below is a sample data structure for the table.

The goal is to display the results for customers with address-type = W and if no then to display the address-type = H. I have tried the the where clause with or clause, case clause and in my attempts I get the both records with W and H address-type.

customerid
address-type
record-count
address1
address2
address3
address4
city
state
zip

123
W
1
123 james ave
Apt 1

City1
AA
11000

123
H
2
134 james ave
Apt 2

City2
AB
23000

124
W
1
145 john ave
Apt 3

City3
AA
32001

124
H
2
155 john ave
Apt 4

City4
AB
12001

125
W
1
1000 wilson ave
Apt 5

City5
AA
12009

126
H
1
11 smith ave
Apt 6

City6
AB
14001

126
H
2
50 third ave
Apt 7

City7
AA
15001

答:
You can use ROW_NUMBER() to order the rows according to your specific logic and then pick the first one only for each customer.

For example:

```<code>select *
from (
  select *,
    row_number() over(partition by customerid order by address_type desc) as rn
  from t
) x
where rn = 1
</code>```

Title: SQL query to get certain matching rows

Body:
You can use ROW_NUMBER() to order the rows according to your specific logic and then pick the first one only for each customer.

For example:

select *
from (
  select *,
    row_number() over(partition by customerid order by address_type desc) as rn
  from t
) x
where rn = 1


问:
SQL Server 2008: update date from row in same column
I've seen this question a lot, but I can't seem to get my SQL to work so I'm hoping someone can help.
I've confirmed that this code will work in Access, but it isn't working with SQL Server 2008.

```<code>UPDATE shop_orders AS t1, shop_orders AS t2
SET t1.shipstreet1 = t2.shipstreet1,
    t1.shipstreet2 = t2.shipstreet2,
    t1.shipcity = t2.shipcity,
    t1.shipregionstate = t2.shipregionstate
WHERE t1.orderid=3292
  AND t2.orderid=3641;
</code>```

Advice?

答:
In SQL Server's T-SQL, you cannot have multiple tables in the UPDATE clause, nor can you give that table a table alias.

You need to use:

```<code>UPDATE shop_orders
FROM shop_orders AS t2
SET shipstreet1 = t2.shipstreet1,
    shipstreet2 = t2.shipstreet2,
    shipcity = t2.shipcity,
    shipregionstate = t2.shipregionstate
WHERE shop_orders.orderid = 3292
  AND t2.orderid = 3641;
</code>```

ContentLicense: CC BY-SA 3.0

Body:
I've seen this question a lot, but I can't seem to get my SQL to work so I'm hoping someone can help.
I've confirmed that this code will work in Access, but it isn't working with SQL Server 2008.

UPDATE shop_orders AS t1, shop_orders AS t2
SET t1.shipstreet1 = t2.shipstreet1,
    t1.shipstreet2 = t2.shipstreet2,
    t1.shipcity = t2.shipcity,
    t1.shipregionstate = t2.shipregionstate
WHERE t1.orderid=3292
  AND t2.orderid=3641;

Advice?

Body:
In SQL Server's T-SQL, you cannot have multiple tables in the UPDATE clause, nor can you give that table a table alias.

You need to use:

UPDATE shop_orders
FROM shop_orders AS t2
SET shipstreet1 = t2.shipstreet1,
    shipstreet2 = t2.shipstreet2,
    shipcity = t2.shipcity,
    shipregionstate = t2.shipregionstate
WHERE shop_orders.orderid = 3292
  AND t2.orderid = 3641;


问:
mysqli Insert from multiple table
I want to insert into mysqli from two table like this

```<code>INSERT INTO oc_lts_plan(vendor_id, subscription_id, name, no_of_product, join_fee, subscription_fee, validity, date_added, date_expire)
SELECT lv.vendor_id
FROM oc_lts_vendor lv
UNION ALL
SELECT ls.subscription_id, lsd.name, ls.no_of_product, ls.join_fee, ls.subscription_fee, ls.validity, now(), (DATE_ADD(now(), INTERVAL 1 month)
FROM oc_lts_subscription ls
    LEFT JOIN oc_lts_subscription_description lsd ON ls.subscription_id=lsd.subscription_id
WHERE ls.default_plan='1'
</code>```

the error: The used SELECT statements have a different number of columns

答:
your second select has no match for the vendor_id column, if the vendor_id column is autogenerate, in this case, you can remove it on the first select

```<code>INSERT INTO oc_lts_plan(subscription_id, name, no_of_product, join_fee, subscription_fee, validity, date_added, date_expire)
SELECT lv.vendor_id
FROM oc_lts_vendor lv
UNION ALL
SELECT ls.subscription_id, lsd.name, ls.no_of_product, ls.join_fee, ls.subscription_fee, ls.validity, now(), (DATE_ADD(now(), INTERVAL 1 month)
FROM oc_lts_subscription ls
    LEFT JOIN oc_lts_subscription_description lsd ON ls.subscription_id=lsd.subscription_id
WHERE ls.default_plan='1'
</code>```

If your primary key is both (vendor_id, subscription_id), you will have no choice but to do the same on your second select, and that will depend on the structure of your second table

Title: mysqli Insert from multiple table

Body:
I want to insert into mysqli from two table like this

INSERT INTO oc_lts_plan(vendor_id, subscription_id, name, no_of_product, join_fee, subscription_fee, validity, date_added, date_expire)
SELECT lv.vendor_id
FROM oc_lts_vendor lv
UNION ALL
SELECT ls.subscription_id, lsd.name, ls.no_of_product, ls.join_fee, ls.subscription_fee, ls.validity, now(), (DATE_ADD(now(), INTERVAL 1 month)
FROM oc_lts_subscription ls
    LEFT JOIN oc_lts_subscription_description lsd ON ls.subscription_id=lsd.subscription_id
WHERE ls.default_plan='1'

the error: The used SELECT statements have a different number of columns

Body:
your second select has no match for the vendor_id column, if the vendor_id column is autogenerate, in this case, you can remove it on the first select

INSERT INTO oc_lts_plan(subscription_id, name, no_of_product, join_fee, subscription_fee, validity, date_added, date_expire)
SELECT lv.vendor_id
FROM oc_lts_vendor lv
UNION ALL
SELECT ls.subscription_id, lsd.name, ls.no_of_product, ls.join_fee, ls.subscription_fee, ls.validity, now(), (DATE_ADD(now(), INTERVAL 1 month)
FROM oc_lts_subscription ls
    LEFT JOIN oc_lts_subscription_description lsd ON ls.subscription_id=lsd.subscription_id
WHERE ls.default_plan='1'

If your primary key is both (vendor_id, subscription_id), you will have no choice but to do the same on your second select, and that will depend on the structure of your second table


问:
How to use `omitempty` with protobuf Timestamp in Golang
I have an optional field on my struct called ExpireTime. It has a time.Time type and a json:"expire_time,omitempty" tag to not send it, when it is empty. This part works perfectly fine.

When I want to use the same field via GRPC, I run into an issue when converting it to the protobuf timestamp format.

```<code>type Timestamp struct {

    // Represents seconds of UTC time since Unix epoch
    // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
    // 9999-12-31T23:59:59Z inclusive.
    Seconds int64 `protobuf:"varint,1,opt,name=seconds,proto3" json:"seconds,omitempty"`
    // Non-negative fractions of a second at nanosecond resolution. Negative
    // second values with fractions must still have non-negative nanos values
    // that count forward in time. Must be from 0 to 999,999,999
    // inclusive.
    Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"`
    // contains filtered or unexported fields
}
</code>```
```<code>ExpireTime *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=expire_time,json=expireTime,proto3" json:"expire_time,omitempty"`
</code>```

The issue is that an empty time.Time{} object will be converted to a negative seconds value corresponding to 0001-01-01T00:00:00Z. Having the omitEmpty flag will not be applied in this case as the value is not zeroed out. What could I do to omit this field, when it is actually empty? Thanks!

答:
As you say time.Time{} converts to 0001-01-01T00:00:00Z; this is working as intended. Note that you also need to be careful converting in the opposite direction (a zero TimeStamp will become 1970-01-01T00:00:00Z).

However generally the Timestamp will be part of a message, for example:

message MyMessage{
   google.protobuf.Timestamp  comm_time = 1;
}
```
<p>Running this through <code>protoc</code> will result in something like:</p>
<pre class="lang-golang prettyprint-override"><code>type MyMessage struct {
    state         protoimpl.MessageState
    sizeCache     protoimpl.SizeCache
    unknownFields protoimpl.UnknownFields

    CommTime *timestamppb.Timestamp `protobuf:"bytes, 1,opt,name=comm_time,json=commTime,proto3" json:"comm_time,omitempty"`
}
</code>```

This means you should be able to achieve the result you are looking for with CommTime=nil; e.g.

sourceTime := time.Time{}  // Whatever time you want to encode
var commTime *timestamp.Timestamp
if !sourceTime.IsZero() {
        commTime = timestamppb.New(sourceTime)
}

msg := MyMessage{
   CommTime: commTime,
}
```

Body:
I have an optional field on my struct called ExpireTime. It has a time.Time type and a json:"expire_time,omitempty" tag to not send it, when it is empty. This part works perfectly fine.

When I want to use the same field via GRPC, I run into an issue when converting it to the protobuf timestamp format.

type Timestamp struct {

    // Represents seconds of UTC time since Unix epoch
    // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
    // 9999-12-31T23:59:59Z inclusive.
    Seconds int64 `protobuf:"varint,1,opt,name=seconds,proto3" json:"seconds,omitempty"`
    // Non-negative fractions of a second at nanosecond resolution. Negative
    // second values with fractions must still have non-negative nanos values
    // that count forward in time. Must be from 0 to 999,999,999
    // inclusive.
    Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"`
    // contains filtered or unexported fields
}

ExpireTime *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=expire_time,json=expireTime,proto3" json:"expire_time,omitempty"`

The issue is that an empty time.Time{} object will be converted to a negative seconds value corresponding to 0001-01-01T00:00:00Z. Having the omitEmpty flag will not be applied in this case as the value is not zeroed out. What could I do to omit this field, when it is actually empty? Thanks!

Body:
As you say time.Time{} converts to 0001-01-01T00:00:00Z; this is working as intended. Note that you also need to be careful converting in the opposite direction (a zero TimeStamp will become 1970-01-01T00:00:00Z).

However generally the Timestamp will be part of a message, for example:

message MyMessage{
   google.protobuf.Timestamp  comm_time = 1;
}

Running this through protoc will result in something like:

type MyMessage struct {
    state         protoimpl.MessageState
    sizeCache     protoimpl.SizeCache
    unknownFields protoimpl.UnknownFields

    CommTime *timestamppb.Timestamp `protobuf:"bytes, 1,opt,name=comm_time,json=commTime,proto3" json:"comm_time,omitempty"`
}

This means you should be able to achieve the result you are looking for with CommTime=nil; e.g.

sourceTime := time.Time{}  // Whatever time you want to encode
var commTime *timestamp.Timestamp
if !sourceTime.IsZero() {
        commTime = timestamppb.New(sourceTime)
}

msg := MyMessage{
   CommTime: commTime,
}


问:
setTimeout macrotask in the UI event handler
i wrote following simple react component

in the onBlur event handler, i create a new macrotask by setTimeout

```<code>function App() {
  const onBlur=()=>{
    console.log('onBlur')
    setTimeout(() => {
      console.log('setTimeout')
    }, 0);
  }

  const onClick=()=>{
    console.log('onClick')
  }

  return (
    <div className="App">
      <div id="first" onClick={onClick}>aaa</div>
      <div id="second" contentEditable onBlur={onBlur} suppressContentEditableWarning>qq</div>
    </div>
  );
}
</code>```

and then

1、i move the mouse pointer into second div

2、then i click the first div

it print out with following sequence in the console

onBlur

setTimeout

onClick

my question is why setTimeout displays before onClick;

apprecaite your answers; please help me; thank you very much;

答:
Because the blur event is fired from the mousedown event, while the click event is made of both mousedown and mouseup.

const d1 = document.querySelector("div");
const d2 = document.querySelector("div[contenteditable]");

d1.addEventListener("mousedown", ({type}) => {
  console.log(type);
  setTimeout(() => console.log("timeout from %s", type), 0);
});
d1.addEventListener("click", ({type}) => console.log(type));
d1.addEventListener("mouseup", ({type}) => console.log(type));
d2.addEventListener("blur", ({type}) => {
  console.log(type);
  setTimeout(() => console.log("timeout from %s", type), 0);
});
d2.focus();

/* expected output:
mousedown
blur
timeout from mousedown
timeout from blur
mouseup
click
*/```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div>CLICK ME</div>
<div contenteditable>focused element</div></code>```

So by the time you release your mouse pointer, the blur event has already been fired and the 0 timeout also had time to get executed, unless if you can do so in less than one ms in Chrome, where they have a 1ms minimum timeout.

Body:
i wrote following simple react component

in the onBlur event handler, i create a new macrotask by setTimeout

function App() {
  const onBlur=()=>{
    console.log('onBlur')
    setTimeout(() => {
      console.log('setTimeout')
    }, 0);
  }

  const onClick=()=>{
    console.log('onClick')
  }

  return (

aaa

qq

  );
}

and then

1、i move the mouse pointer into second div

2、then i click the first div

it print out with following sequence in the console

onBlur

setTimeout

onClick

my question is why setTimeout displays before onClick;

apprecaite your answers; please help me; thank you very much;

Body:
Because the blur event is fired from the mousedown event, while the click event is made of both mousedown and mouseup.

const d1 = document.querySelector("div");
const d2 = document.querySelector("div[contenteditable]");

d1.addEventListener("mousedown", ({type}) => {
  console.log(type);
  setTimeout(() => console.log("timeout from %s", type), 0);
});
d1.addEventListener("click", ({type}) => console.log(type));
d1.addEventListener("mouseup", ({type}) => console.log(type));
d2.addEventListener("blur", ({type}) => {
  console.log(type);
  setTimeout(() => console.log("timeout from %s", type), 0);
});
d2.focus();

/* expected output:
mousedown
blur
timeout from mousedown
timeout from blur
mouseup
click
*/

<div>CLICK ME</div>
<div contenteditable>focused element</div>

So by the time you release your mouse pointer, the blur event has already been fired and the 0 timeout also had time to get executed, unless if you can do so in less than one ms in Chrome, where they have a 1ms minimum timeout.


问:
"Temporary value dropped while borrowed" when using string.replace()
Can someone explain which exact temporary value is dropped and what the recommended way to do this operation is?</p>
```<code>fn main() {
    let mut a = &mut String::from("Hello Ownership");
    a = &mut a.replace("Ownership", "World");
    println!("a is {}", a);
}
</code>```

答:
Why are you using &mut there? Try this:

fn main() {
    let mut a = String::from("Hello Ownership");
    a = a.replace("Ownership", "World");
    println!("a is {}", a);
}
```

Body:
Can someone explain which exact temporary value is dropped and what the recommended way to do this operation is?

fn main() {
    let mut a = &mut String::from("Hello Ownership");
    a = &mut a.replace("Ownership", "World");
    println!("a is {}", a);
}


问:
How to add drawer in bottom navigation bar in flutter?
I want to show a drawer when user clicks on the 4th(more_vert) icon, but I am not able to implement it. In my current implementation when 4th icon is clicked flutter takes me to a new page and there shows the drawer not over the current screen as it should. What am I doing wrong ? Also what is the differnce between BottomNavigationBar and BottomAppBar I could not find the difference anywhere. I checked out a few articles and it I think BottomAppBar is used to show the Fab floating in the bottom appbar. Is there any other difference between the two and when should one use one over the other.

```<code>class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  List<Widget> _widgetOptions = <Widget>[
    Page1(),
    Page2(),
    Page3(),
    Page4(),   // this page implements the drawer

  ];
  int _currentSelected = 0;

  void _onItemTapped(int index) {
    setState(() {
      _currentSelected = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: _widgetOptions.elementAt(_currentSelected),
      bottomNavigationBar: BottomNavigationBar(
        type: BottomNavigationBarType.fixed,
        onTap: _onItemTapped,
        currentIndex: _currentSelected,
        showUnselectedLabels: true,
        unselectedItemColor: Colors.grey[800],
        selectedItemColor: Color.fromRGBO(10, 135, 255, 1),
        items: <BottomNavigationBarItem>[
          BottomNavigationBarItem(
             icon: Icon(AntDesign.carryout),
          ),
          BottomNavigationBarItem(
             icon: Icon(MaterialCommunityIcons.sack),
          ),
          BottomNavigationBarItem(
             icon: Icon(Octicons.archive),
          ),
          BottomNavigationBarItem(
             icon: Icon(Icons.more_vert),
          )
        ],
      ),
      // backgroundColor: Colors.black,
    );
  }
}
</code>```

答:
The solutions provided above work if you are not using the newer versions of Flutter with Null Safety. In case you are using Flutter 2.0 or greater. Due to Null Safety, you will get an error saying:

```<code>The method 'openDrawer' can't be unconditionally invoked because the receiver can be 'null'.
Try making the call conditional (using '?.') or adding a null check to the target
</code>```

Use: _drawerKey.currentState!.openDrawer();

Body:
I want to show a drawer when user clicks on the 4th(more_vert) icon, but I am not able to implement it. In my current implementation when 4th icon is clicked flutter takes me to a new page and there shows the drawer not over the current screen as it should. What am I doing wrong ? Also what is the differnce between BottomNavigationBar and BottomAppBar I could not find the difference anywhere. I checked out a few articles and it I think BottomAppBar is used to show the Fab floating in the bottom appbar. Is there any other difference between the two and when should one use one over the other.

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  List<Widget> _widgetOptions = <Widget>[
    Page1(),
    Page2(),
    Page3(),
    Page4(),   // this page implements the drawer

  ];
  int _currentSelected = 0;

  void _onItemTapped(int index) {
    setState(() {
      _currentSelected = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: _widgetOptions.elementAt(_currentSelected),
      bottomNavigationBar: BottomNavigationBar(
        type: BottomNavigationBarType.fixed,
        onTap: _onItemTapped,
        currentIndex: _currentSelected,
        showUnselectedLabels: true,
        unselectedItemColor: Colors.grey[800],
        selectedItemColor: Color.fromRGBO(10, 135, 255, 1),
        items: <BottomNavigationBarItem>[
          BottomNavigationBarItem(
             icon: Icon(AntDesign.carryout),
          ),
          BottomNavigationBarItem(
             icon: Icon(MaterialCommunityIcons.sack),
          ),
          BottomNavigationBarItem(
             icon: Icon(Octicons.archive),
          ),
          BottomNavigationBarItem(
             icon: Icon(Icons.more_vert),
          )
        ],
      ),
      // backgroundColor: Colors.black,
    );
  }
}

Body:
The solutions provided above work if you are not using the newer versions of Flutter with Null Safety. In case you are using Flutter 2.0 or greater. Due to Null Safety, you will get an error saying:

The method 'openDrawer' can't be unconditionally invoked because the receiver can be 'null'.
Try making the call conditional (using '?.') or adding a null check to the target

Use: _drawerKey.currentState!.openDrawer();