问:
Retrofit can't connect to hapi server localhost?
I'm building android apps using retrofit as my httprequest to connect to my hapi server. my server is working fine, I've test it on postman and my WebApps. But my retrofit can not connect to it. below is my code. For the sake of simplicity to read I delete lines that not necessary:

LoginActivity.java

```<code>package com.sianghee.reviu;

import android.app.Activity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.support.design.widget.TextInputEditText;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;

import android.content.Intent;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import butterknife.ButterKnife;
import butterknife.BindView;
import butterknife.OnClick;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

import com.sianghee.reviu.interfaces.APIService;
import com.sianghee.reviu.lib.Session;
import com.sianghee.reviu.models.UserLogin;
import static com.sianghee.reviu.lib.Helper.returnError;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;

public class LoginActivity extends Activity {
    private static final String TAG = "LoginActivity";
    private static final int REQUEST_SIGNUP = 0;
    Session session;
    public static final String BASE_URL = "localhost:3000";

    private EditText emailText;
    private EditText passwordText;

     @BindView(R.id.btn_login) Button _loginButton;
    @BindView(R.id.link_signup) TextView _signupLink;

    // TODO: Init sewaktu pertama kali form diload
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        ButterKnife.bind(this);

        emailText = (EditText)findViewById(R.id.input_email);
        passwordText = (EditText)findViewById(R.id.input_password);

    }

    // TODO: bind login and do login
    @OnClick(R.id.btn_login)
    public void submitLogin() {
        login();
    }

    // TODO: bind signup and do register
    ....

    public void login() {
        Log.d(TAG, "Login");

        if (!validate()) {
            onLoginFailed();
            return;
        }

        _loginButton.setEnabled(false);

        final ProgressDialog progressDialog = new ProgressDialog(this);
        progressDialog.setIndeterminate(true);
        progressDialog.setMessage("Authenticating...");
        progressDialog.show();

        String email = emailText.getText().toString();
        String password = passwordText.getText().toString();

        // TODO: Implement your own authentication logic here.
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        APIService api = retrofit.create(APIService.class);
        UserLogin userLogin = new UserLogin(email, password);

        Call<UserLogin> call = api.login(userLogin);
        call.enqueue(new Callback<UserLogin>() {
            @Override
            public void onResponse(Call<UserLogin> call, Response<UserLogin> response) {
                String result;
                progressDialog.dismiss();
                try {
                    result = response.body().toString();

                    if (returnError(result).isEmpty()) {

                        JSONObject obj;
                        obj = new JSONObject(result);
                        session.setLoginSession(obj.getString("scope"), obj.getString("token"));

                        Intent i = new Intent(LoginActivity.this, MainActivity.class);
                        i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
                        startActivity(i);
                        finish();

                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }

            }

            .......
}
</code>```

APIService.java

```<code>package com.sianghee.reviu.interfaces;

import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.POST;

import com.sianghee.reviu.models.UserLogin;

/**
 * Created by andy on 11/26/17.
 */

public interface APIService {
    @POST("auth")
    Call<UserLogin> login(@Body UserLogin auth);
}
</code>```

UserLogin.java

```<code>package com.sianghee.reviu.models;

public class UserLogin {
    String email;
    String password;

    public UserLogin(String email, String password) {
        this.email = email;
        this.password = password;
    }
}
</code>```

Whenever I clicked the login button, It's failed to connect to server. below is the logcat:

```<code>12-02 23:24:42.771 3660-3660/com.sianghee.reviu I/InstantRun: starting instant run server: is main process
12-02 23:24:43.116 3660-3690/com.sianghee.reviu D/OpenGLRenderer: HWUI GL Pipeline
12-02 23:24:43.213 3660-3660/com.sianghee.reviu I/TextInputLayout: EditText added is not a TextInputEditText. Please switch to using that class instead.
12-02 23:24:43.219 3660-3660/com.sianghee.reviu I/TextInputLayout: EditText added is not a TextInputEditText. Please switch to using that class instead.

                                                                   [ 12-02 23:24:43.283  3660: 3690 D/         ]
                                                                   HostConnection::get() New Host Connection established 0x896438c0, tid 3690
12-02 23:24:43.471 3660-3690/com.sianghee.reviu I/zygote: android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasWideColorDisplay retrieved: 0
12-02 23:24:43.471 3660-3690/com.sianghee.reviu I/OpenGLRenderer: Initialized EGL, version 1.4
12-02 23:24:43.471 3660-3690/com.sianghee.reviu D/OpenGLRenderer: Swap behavior 1
12-02 23:24:43.471 3660-3690/com.sianghee.reviu W/OpenGLRenderer: Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without...
12-02 23:24:43.471 3660-3690/com.sianghee.reviu D/OpenGLRenderer: Swap behavior 0
12-02 23:24:43.473 3660-3690/com.sianghee.reviu D/EGL_emulation: eglCreateContext: 0x9b543860: maj 2 min 0 rcv 2
12-02 23:24:43.475 3660-3690/com.sianghee.reviu D/EGL_emulation: eglMakeCurrent: 0x9b543860: ver 2 0 (tinfo 0xa4a8f700)
12-02 23:24:43.527 3660-3690/com.sianghee.reviu D/EGL_emulation: eglMakeCurrent: 0x9b543860: ver 2 0 (tinfo 0xa4a8f700)
12-02 23:24:43.856 3660-3660/com.sianghee.reviu I/AssistStructure: Flattened final assist data: 1684 bytes, containing 1 windows, 5 views
12-02 23:24:49.113 3660-3673/com.sianghee.reviu I/zygote: Do partial code cache collection, code=30KB, data=26KB
12-02 23:24:49.113 3660-3673/com.sianghee.reviu I/zygote: After code cache collection, code=30KB, data=26KB
12-02 23:24:49.113 3660-3673/com.sianghee.reviu I/zygote: Increasing code cache capacity to 128KB
12-02 23:24:51.355 3660-3673/com.sianghee.reviu I/zygote: Do partial code cache collection, code=61KB, data=59KB
12-02 23:24:51.356 3660-3673/com.sianghee.reviu I/zygote: After code cache collection, code=61KB, data=59KB
12-02 23:24:51.356 3660-3673/com.sianghee.reviu I/zygote: Increasing code cache capacity to 256KB
12-02 23:24:54.016 3660-3673/com.sianghee.reviu I/zygote: Do full code cache collection, code=123KB, data=99KB
12-02 23:24:54.016 3660-3673/com.sianghee.reviu I/zygote: After code cache collection, code=107KB, data=66KB
12-02 23:24:56.503 3660-3660/com.sianghee.reviu D/LoginActivity: Login
12-02 23:24:56.573 3660-3673/com.sianghee.reviu I/zygote: Do partial code cache collection, code=114KB, data=93KB
12-02 23:24:56.573 3660-3673/com.sianghee.reviu I/zygote: After code cache collection, code=114KB, data=93KB
12-02 23:24:56.573 3660-3673/com.sianghee.reviu I/zygote: Increasing code cache capacity to 512KB
12-02 23:24:56.574 3660-3673/com.sianghee.reviu I/zygote: JIT allocated 56KB for compiled code of void android.view.View.<init>(android.content.Context, android.util.AttributeSet, int, int)
12-02 23:24:56.603 3660-3660/com.sianghee.reviu D/NetworkSecurityConfig: No Network Security Config specified, using platform default
12-02 23:24:56.803 3660-3660/com.sianghee.reviu W/error: java.net.ConnectException: Failed to connect to /127.0.0.1:3000
12-02 23:24:57.094 3660-3690/com.sianghee.reviu D/EGL_emulation: eglMakeCurrent: 0x9b543860: ver 2 0 (tinfo 0xa4a8f700)
12-02 23:24:57.126 3660-3690/com.sianghee.reviu D/EGL_emulation: eglMakeCurrent: 0x9b543860: ver 2 0 (tinfo 0xa4a8f700)
</code>```

My server API Url for login is : http://127.0.0.1:3000/auth

notice that error from my Log.w() method before that say:

java.net.ConnectException: Failed to connect to /127.0.0.1:3000

Maybe this is just my common mistake, please help.

答:
make sure that your phone(emulator) and your computer are in a same network
and use ip adress http://192.168.8.106:3030 for example, instead of http://localhost:3030</p>

Body:
I'm building android apps using retrofit as my httprequest to connect to my hapi server. my server is working fine, I've test it on postman and my WebApps. But my retrofit can not connect to it. below is my code. For the sake of simplicity to read I delete lines that not necessary:

LoginActivity.java

package com.sianghee.reviu;

import android.app.Activity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.support.design.widget.TextInputEditText;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;

import android.content.Intent;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import butterknife.ButterKnife;
import butterknife.BindView;
import butterknife.OnClick;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

import com.sianghee.reviu.interfaces.APIService;
import com.sianghee.reviu.lib.Session;
import com.sianghee.reviu.models.UserLogin;
import static com.sianghee.reviu.lib.Helper.returnError;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;

public class LoginActivity extends Activity {
    private static final String TAG = "LoginActivity";
    private static final int REQUEST_SIGNUP = 0;
    Session session;
    public static final String BASE_URL = "localhost:3000";

    private EditText emailText;
    private EditText passwordText;

     @BindView(R.id.btn_login) Button _loginButton;
    @BindView(R.id.link_signup) TextView _signupLink;

    // TODO: Init sewaktu pertama kali form diload
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        ButterKnife.bind(this);

        emailText = (EditText)findViewById(R.id.input_email);
        passwordText = (EditText)findViewById(R.id.input_password);

    }

    // TODO: bind login and do login
    @OnClick(R.id.btn_login)
    public void submitLogin() {
        login();
    }

    // TODO: bind signup and do register
    ....

    public void login() {
        Log.d(TAG, "Login");

        if (!validate()) {
            onLoginFailed();
            return;
        }

        _loginButton.setEnabled(false);

        final ProgressDialog progressDialog = new ProgressDialog(this);
        progressDialog.setIndeterminate(true);
        progressDialog.setMessage("Authenticating...");
        progressDialog.show();

        String email = emailText.getText().toString();
        String password = passwordText.getText().toString();

        // TODO: Implement your own authentication logic here.
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        APIService api = retrofit.create(APIService.class);
        UserLogin userLogin = new UserLogin(email, password);

        Call<UserLogin> call = api.login(userLogin);
        call.enqueue(new Callback<UserLogin>() {
            @Override
            public void onResponse(Call<UserLogin> call, Response<UserLogin> response) {
                String result;
                progressDialog.dismiss();
                try {
                    result = response.body().toString();

                    if (returnError(result).isEmpty()) {

                        JSONObject obj;
                        obj = new JSONObject(result);
                        session.setLoginSession(obj.getString("scope"), obj.getString("token"));

                        Intent i = new Intent(LoginActivity.this, MainActivity.class);
                        i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
                        startActivity(i);
                        finish();

                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }

            }

            .......
}

APIService.java

package com.sianghee.reviu.interfaces;

import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.POST;

import com.sianghee.reviu.models.UserLogin;

/**
 * Created by andy on 11/26/17.
 */

public interface APIService {
    @POST("auth")
    Call<UserLogin> login(@Body UserLogin auth);
}

UserLogin.java

package com.sianghee.reviu.models;

public class UserLogin {
    String email;
    String password;

    public UserLogin(String email, String password) {
        this.email = email;
        this.password = password;
    }
}

Whenever I clicked the login button, It's failed to connect to server. below is the logcat:

12-02 23:24:42.771 3660-3660/com.sianghee.reviu I/InstantRun: starting instant run server: is main process
12-02 23:24:43.116 3660-3690/com.sianghee.reviu D/OpenGLRenderer: HWUI GL Pipeline
12-02 23:24:43.213 3660-3660/com.sianghee.reviu I/TextInputLayout: EditText added is not a TextInputEditText. Please switch to using that class instead.
12-02 23:24:43.219 3660-3660/com.sianghee.reviu I/TextInputLayout: EditText added is not a TextInputEditText. Please switch to using that class instead.

                                                                   [ 12-02 23:24:43.283  3660: 3690 D/         ]
                                                                   HostConnection::get() New Host Connection established 0x896438c0, tid 3690
12-02 23:24:43.471 3660-3690/com.sianghee.reviu I/zygote: android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasWideColorDisplay retrieved: 0
12-02 23:24:43.471 3660-3690/com.sianghee.reviu I/OpenGLRenderer: Initialized EGL, version 1.4
12-02 23:24:43.471 3660-3690/com.sianghee.reviu D/OpenGLRenderer: Swap behavior 1
12-02 23:24:43.471 3660-3690/com.sianghee.reviu W/OpenGLRenderer: Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without...
12-02 23:24:43.471 3660-3690/com.sianghee.reviu D/OpenGLRenderer: Swap behavior 0
12-02 23:24:43.473 3660-3690/com.sianghee.reviu D/EGL_emulation: eglCreateContext: 0x9b543860: maj 2 min 0 rcv 2
12-02 23:24:43.475 3660-3690/com.sianghee.reviu D/EGL_emulation: eglMakeCurrent: 0x9b543860: ver 2 0 (tinfo 0xa4a8f700)
12-02 23:24:43.527 3660-3690/com.sianghee.reviu D/EGL_emulation: eglMakeCurrent: 0x9b543860: ver 2 0 (tinfo 0xa4a8f700)
12-02 23:24:43.856 3660-3660/com.sianghee.reviu I/AssistStructure: Flattened final assist data: 1684 bytes, containing 1 windows, 5 views
12-02 23:24:49.113 3660-3673/com.sianghee.reviu I/zygote: Do partial code cache collection, code=30KB, data=26KB
12-02 23:24:49.113 3660-3673/com.sianghee.reviu I/zygote: After code cache collection, code=30KB, data=26KB
12-02 23:24:49.113 3660-3673/com.sianghee.reviu I/zygote: Increasing code cache capacity to 128KB
12-02 23:24:51.355 3660-3673/com.sianghee.reviu I/zygote: Do partial code cache collection, code=61KB, data=59KB
12-02 23:24:51.356 3660-3673/com.sianghee.reviu I/zygote: After code cache collection, code=61KB, data=59KB
12-02 23:24:51.356 3660-3673/com.sianghee.reviu I/zygote: Increasing code cache capacity to 256KB
12-02 23:24:54.016 3660-3673/com.sianghee.reviu I/zygote: Do full code cache collection, code=123KB, data=99KB
12-02 23:24:54.016 3660-3673/com.sianghee.reviu I/zygote: After code cache collection, code=107KB, data=66KB
12-02 23:24:56.503 3660-3660/com.sianghee.reviu D/LoginActivity: Login
12-02 23:24:56.573 3660-3673/com.sianghee.reviu I/zygote: Do partial code cache collection, code=114KB, data=93KB
12-02 23:24:56.573 3660-3673/com.sianghee.reviu I/zygote: After code cache collection, code=114KB, data=93KB
12-02 23:24:56.573 3660-3673/com.sianghee.reviu I/zygote: Increasing code cache capacity to 512KB
12-02 23:24:56.574 3660-3673/com.sianghee.reviu I/zygote: JIT allocated 56KB for compiled code of void android.view.View.<init>(android.content.Context, android.util.AttributeSet, int, int)
12-02 23:24:56.603 3660-3660/com.sianghee.reviu D/NetworkSecurityConfig: No Network Security Config specified, using platform default
12-02 23:24:56.803 3660-3660/com.sianghee.reviu W/error: java.net.ConnectException: Failed to connect to /127.0.0.1:3000
12-02 23:24:57.094 3660-3690/com.sianghee.reviu D/EGL_emulation: eglMakeCurrent: 0x9b543860: ver 2 0 (tinfo 0xa4a8f700)
12-02 23:24:57.126 3660-3690/com.sianghee.reviu D/EGL_emulation: eglMakeCurrent: 0x9b543860: ver 2 0 (tinfo 0xa4a8f700)

My server API Url for login is : http://127.0.0.1:3000/auth

notice that error from my Log.w() method before that say:

java.net.ConnectException: Failed to connect to /127.0.0.1:3000

Maybe this is just my common mistake, please help.


来源: stackexchange

问:
External Methods for Plone/Zope
I have two instances of Plone running on a server - their locations are /usr/local/Plone/Inst1 and /usr/local/Plone/Inst2.  I'm trying to setup external methods, but am having a difficult time figuring out where my "Extensions" folder should be placed.  It seems that where ever I place it, the ZMI never sees it.  I have tried:

/usr/local/Plone/Extensions
/usr/local/Plone/Inst1/Extensions

...and various other sub-folders within the "Inst1" directory.  When I add an external method, I've tried adding it at both the root of the ZMI ("/") and in the Instance folder ("/Inst1/").  When I add it to the root, I get a message that says "The specified module, demo, could not be found."  When I try to add it in the instance folder, I get an error page that says "This page does not seem to exist..."

It appears that the ZMI is failing to find that file ("demo.py").  Is there a particular place it should be stored?

After looking over documentation from Zope's site (and numerous tutorials), it should be in the "Zope" folder - but I don't have any such folder (nor does any folder named "Extensions" exist on the file system, other than the one I created in the "Plone" and "Plone/Inst1" directories).

答:
Depending on what version of Plone you have installed will change this, but it is likely something like:

/path/to/plone/install/parts/instance/Extensions

Or

/path/to/plone/install/parts/client1/Extensions

You're probably better off putting the external method in a product though since placing an external method in it's "parts" instance folder will mean it will be wiped out every time you run buildout. Then if you're going to make a product out of it, you might as will do a traversable view utility like "@@plone_context_state" and "@@plone_portal_state" which is usually a better way to do it.

ContentLicense: CC BY-SA 3.0

Title: External Methods for Plone/Zope


问:
REST server endpoint to check if an authenticated user has access or permission to do an action
I have an Angular single page app where users can create a job listing. I want to control whether or not a user can edit a job listing. There are two roles that can edit a job listing. A authenticated user that can edit their own job listing or an administrator who can edit all job listings.

The server will test if a user has access to these actions. That is not a problem. However, before the state changes in the client app, I want to make a request to the server to check if the current logged in user has permission. So the request will check if a user can edit a job listing with #id 9de88893, for example.

What is that route look like. Does it only return true or false? I can't even imagine how this looks or how it would work. Any ideas?

答:
You might think in a different approach for that case.

I assume:

I assume you know your logged user_id on the client sid;

A user has a ROLE and an ID;

Suggestion:

Add the Job owner (posting user_id) to your Job DTO (could be owner_id);

Validate if a user is ADMIN or user_id == job.owner_id

Hope this helps in some way :)

ContentLicense: CC BY-SA 4.0


问:
Simple timer App where it counts the number of seconds that have gone by since it's start shows an incorrect time
I am new to flutter and decided to build a simple timer app, that counts the number of seconds that have gone by since it's start and it ends up showing the wrong time. The timer starts off with 0, then increments to 1 and, from there on out it seems as if it is increasing exponentially.

main.dart

```<code>import 'package:flutter/material.dart';
import 'app.dart';

void main() => runApp(App());
</code>```

app.dart

```<code>import 'package:flutter/material.dart';
import 'package:async/async.dart';
import 'clock_widget.dart';

class App extends StatelessWidget {
 @override

 Widget build(BuildContext context) {
  return MaterialApp(
  title: "Timer",
  home: Scaffold(
    appBar: AppBar(
      title: Text("Timer"),
      centerTitle: true,
    ),
    body: Row(
      mainAxisSize: MainAxisSize.max,
      crossAxisAlignment: CrossAxisAlignment.center,
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Column(
          mainAxisSize: MainAxisSize.max,
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            ClockWidget(),
            Text("seconds", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 35),)
          ],
        )
      ],
    )
  ),
);
}
</code>```

clock_widget.dart

```<code>import 'dart:async';
import 'package:flutter/material.dart';

class ClockWidget extends StatefulWidget {
  @override
  ClockWidgetState createState() => ClockWidgetState();
}

class ClockWidgetState extends State<ClockWidget> {
  @override
  int _secondCount = 0;

  Widget build(BuildContext context) {
    Timer.periodic(Duration(seconds: 1), (Timer t) => (setState(() {_secondCount+=1;})));
    print("${_secondCount}");
    return Text("${_secondCount}", style: TextStyle(fontSize: 75, color: Color.fromRGBO(30, 144, 255, 1)),);
  }
}
</code>```

I have tried numberous methods but to me this seemed like the simplest one and logically it seems correct. After every second setState is called which increments _secondsCount.

The app's second count hardly 15 seconds after running it.

答:
You are currently defining new Timers every second. Each of these timers is incrementing the number of seconds.

You want to define your Timer only once and outside of the build method.

Create a Timer in initState

Update state every second

Display the seconds in the build method

Cancel the Timer in dispose

Here's an example:

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

class ClockWidgetState extends State<ClockWidget> {
  Timer _timer;
  int _secondCount = 0;

  @override
  void initState() {
    super.initState();
    _timer = Timer.periodic(Duration(seconds: 1), (timer) {
      setState(() {
        this._secondCount += 1;
      });
    });
  }

  Widget build(BuildContext context) {
    print("${_secondCount}");
    return Text(
      "${_secondCount}",
      style: TextStyle(fontSize: 75, color: Color.fromRGBO(30, 144, 255, 1)),
    );
  }

  @override
  void dispose() {
    _timer.cancel();
    super.dispose();
  }
}
</code>```

Body:
I am new to flutter and decided to build a simple timer app, that counts the number of seconds that have gone by since it's start and it ends up showing the wrong time. The timer starts off with 0, then increments to 1 and, from there on out it seems as if it is increasing exponentially.

main.dart

import 'package:flutter/material.dart';
import 'app.dart';

void main() => runApp(App());

app.dart

import 'package:flutter/material.dart';
import 'package:async/async.dart';
import 'clock_widget.dart';

class App extends StatelessWidget {
 @override

 Widget build(BuildContext context) {
  return MaterialApp(
  title: "Timer",
  home: Scaffold(
    appBar: AppBar(
      title: Text("Timer"),
      centerTitle: true,
    ),
    body: Row(
      mainAxisSize: MainAxisSize.max,
      crossAxisAlignment: CrossAxisAlignment.center,
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Column(
          mainAxisSize: MainAxisSize.max,
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            ClockWidget(),
            Text("seconds", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 35),)
          ],
        )
      ],
    )
  ),
);
}

clock_widget.dart

import 'dart:async';
import 'package:flutter/material.dart';

class ClockWidget extends StatefulWidget {
  @override
  ClockWidgetState createState() => ClockWidgetState();
}

class ClockWidgetState extends State<ClockWidget> {
  @override
  int _secondCount = 0;

  Widget build(BuildContext context) {
    Timer.periodic(Duration(seconds: 1), (Timer t) => (setState(() {_secondCount+=1;})));
    print("${_secondCount}");
    return Text("${_secondCount}", style: TextStyle(fontSize: 75, color: Color.fromRGBO(30, 144, 255, 1)),);
  }
}

I have tried numberous methods but to me this seemed like the simplest one and logically it seems correct. After every second setState is called which increments _secondsCount.

The app's second count hardly 15 seconds after running it.

Body:
You are currently defining new Timers every second. Each of these timers is incrementing the number of seconds.

You want to define your Timer only once and outside of the build method.

Create a Timer in initState

Update state every second

Display the seconds in the build method

Cancel the Timer in dispose

Here's an example:

class ClockWidget extends StatefulWidget {
  @override
  ClockWidgetState createState() => ClockWidgetState();
}

class ClockWidgetState extends State<ClockWidget> {
  Timer _timer;
  int _secondCount = 0;

  @override
  void initState() {
    super.initState();
    _timer = Timer.periodic(Duration(seconds: 1), (timer) {
      setState(() {
        this._secondCount += 1;
      });
    });
  }

  Widget build(BuildContext context) {
    print("${_secondCount}");
    return Text(
      "${_secondCount}",
      style: TextStyle(fontSize: 75, color: Color.fromRGBO(30, 144, 255, 1)),
    );
  }

  @override
  void dispose() {
    _timer.cancel();
    super.dispose();
  }
}


问:
PostgresSQL Alter column giving invalid input syntax for type date: ""
I'm not super experienced at this, but I have a column which now houses stings which need to be altered to dates. It's giving me an error for when there are only empty strings. Here's what's up.

```<code>ALTER TABLE artist
ALTER COLUMN available_from TYPE date USING available_from::date;
</code>```

This is giving me the following error:

```<code>invalid input syntax for type date: ""
</code>```

Then I tried

```<code>ALTER TABLE artist
ALTER COLUMN available_from TYPE date USING (NULLIF(available_from),'')::date,
</code>```

Which gave me:

```<code>syntax error at or near ")"
</code>```

Anyone who can help me out with this?

答:
You misplaced the ) in the second statement:

```<code>ALTER TABLE artist
   ALTER COLUMN available_from TYPE date
   USING (NULLIF(available_from,''))::date,
                                   ^
                                   | here
</code>```

Body:
I'm not super experienced at this, but I have a column which now houses stings which need to be altered to dates. It's giving me an error for when there are only empty strings. Here's what's up.

ALTER TABLE artist
ALTER COLUMN available_from TYPE date USING available_from::date;

This is giving me the following error:

invalid input syntax for type date: ""

Then I tried

ALTER TABLE artist
ALTER COLUMN available_from TYPE date USING (NULLIF(available_from),'')::date,

Which gave me:

syntax error at or near ")"

Anyone who can help me out with this?

Body:
You misplaced the ) in the second statement:

ALTER TABLE artist
   ALTER COLUMN available_from TYPE date
   USING (NULLIF(available_from,''))::date,
                                   ^
                                   | here


问:
The toggle in the script isn't working for me
I'm using this code that I found online, but it's not working completely the way I want it to.

Basically I am wanting check boxes to hide divs based on the users selection.
I am building an allergens advice page for a restaurant. When a guest selects the allergens they have I want it to hide the dishes that they cannot have.

The above code works perfectly if the guest has one allergen. It hides the div. If they select more than one then the box will reappear.

$(document).ready(function() {
    $('input[type="checkbox"]').click(function() {
    var inputValue = $(this).attr("value");
    $("." + inputValue).toggle();
});```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="selectt Eggs Gluten">
    <strong>Dough Balls</strong><br/>
    Cheese dough balls served with chipotle butter.
</div>
<ul>
    <li>
        <input type="checkbox" id="checkboxThree" value="Eggs">
        <label for="checkboxThree"> Eggs</label>
    </li>
</ul></code>```

I'm guessing it's doing it because the code is toggling, but I don't know of any other code to prevent that.
Your help would be greatly appreciated.

答:
Your code throws unexpected end of input, you are missing closing parentheses for $(document).ready():

$(document).ready(function() {
                $('input[type="checkbox"]').click(function() {
                    var inputValue = $(this).attr("value");
                    $("." + inputValue).toggle();
                });

  });```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="selectt Eggs Gluten">
        <strong>Dough Balls</strong><br/>
        Cheese dough balls served with chipotle butter.</div>
            <li>
                <input type="checkbox" id="checkboxThree" value="Eggs">
                <label for="checkboxThree"> Eggs</label>
            </li></code>```

In the case of multiple checkboxes that refer to the same product that should stay hidden:

   $(document).ready(function() {
                    $('input[type="checkbox"]').click(function() {
                            var inputValue = $(this).val();

                            if($(this).is(':checked')){
                               $("." + inputValue).hide();
                            }else{
                               $("." + inputValue).show();
                            }
                    });

      });```
<pre class="snippet-code-html lang-html prettyprint-override"><code>    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div class="selectt Eggs Gluten">
            <strong>Dough Balls</strong><br/>
            Cheese dough balls served with chipotle butter.</div>
                <li>
                    <input type="checkbox" id="checkboxThree" value="Eggs">
                    <label for="checkboxThree"> Eggs</label>
                </li>
                <li>
                    <input type="checkbox" id="checkbox4" value="Gluten">
                    <label for="checkbox4"> Gluten</label>
                </li>
 </code>```

Body:
I'm using this code that I found online, but it's not working completely the way I want it to.

Basically I am wanting check boxes to hide divs based on the users selection.
I am building an allergens advice page for a restaurant. When a guest selects the allergens they have I want it to hide the dishes that they cannot have.

The above code works perfectly if the guest has one allergen. It hides the div. If they select more than one then the box will reappear.

$(document).ready(function() {
    $('input[type="checkbox"]').click(function() {
    var inputValue = $(this).attr("value");
    $("." + inputValue).toggle();
});

    Dough Balls

    Cheese dough balls served with chipotle butter.

        <input type="checkbox" id="checkboxThree" value="Eggs">
         Eggs

I'm guessing it's doing it because the code is toggling, but I don't know of any other code to prevent that.
Your help would be greatly appreciated.

Body:
Your code throws unexpected end of input, you are missing closing parentheses for $(document).ready():

$(document).ready(function() {
                $('input[type="checkbox"]').click(function() {
                    var inputValue = $(this).attr("value");
                    $("." + inputValue).toggle();
                });

  });

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="selectt Eggs Gluten">
        <strong>Dough Balls</strong><br/>
        Cheese dough balls served with chipotle butter.</div>
            <li>
                <input type="checkbox" id="checkboxThree" value="Eggs">
                <label for="checkboxThree"> Eggs</label>
            </li>

In the case of multiple checkboxes that refer to the same product that should stay hidden:

   $(document).ready(function() {
                    $('input[type="checkbox"]').click(function() {
                            var inputValue = $(this).val();

                            if($(this).is(':checked')){
                               $("." + inputValue).hide();
                            }else{
                               $("." + inputValue).show();
                            }
                    });

      });

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div class="selectt Eggs Gluten">
            <strong>Dough Balls</strong><br/>
            Cheese dough balls served with chipotle butter.</div>
                <li>
                    <input type="checkbox" id="checkboxThree" value="Eggs">
                    <label for="checkboxThree"> Eggs</label>
                </li>
                <li>
                    <input type="checkbox" id="checkbox4" value="Gluten">
                    <label for="checkbox4"> Gluten</label>
                </li>


问:
Object reference not set to an instance of an object when assigning Object(Integer) value to Row field of Object(integer) Type
```<code>Dim size As Integer

Dim PivotDatasource As IEnumerable(Of PivotDrillDownDataRow)

for each row as PivotDrillDownDataRow in PivotDatasource
   row(dataField.FieldName)=row(dataField.FieldName)+size

next
</code>```

答:
You aren't getting the null reference on the line where you assign the variable, you're getting it on the line above:

In your code, PivotDatasource is null because you have declared it as a variable that holds a certain type of object but you haven't actually given it any value.

This will result in a NullReferenceException when you try to iterate over it. You can't iterate over a variable that is null, because the compiler will (behind the scenes) call on it to provide an enumerator and if it's null that call will fail

The compiler will also have warned you about this before you ran your app (see the green wiggly underline and Warnings window):

To resolve the problem, ensure that PivotDatasource is initialized to a value of some collection of PivotDrillDownDataRow. How you do this will be something that we cannot easily say given the small fragment of cod you've posted


问:
MySQL connection refused from Node on first run only (docker-compose)
I'm trying to build out a NodeJS/MySQL stack, but am experiencing an intermittent issue.

Here is my docker compose file:

```<code>version: '3'
services:
    db:
        image: mysql:5.7
        command: --default-authentication-plugin=mysql_native_password
        ports:
            - "3306:3306"
        environment:
            MYSQL_ROOT_PASSWORD: root
        container_name: 'db'
        networks:
            - db-network
        volumes:
            - db-data:/var/lib/mysql
            - ./db:/docker-entrypoint-initdb.d
    forum:
        image: "node:12"
        user: "node"
        working_dir: /home/node/app
        depends_on:
            - db
        ports:
            - 7000:3000
        environment:
          - NODE_ENV=development
          - PORT=3000
        volumes:
          - ./server:/home/node/app
        command: "npm start"
        networks:
            - db-network
    adminer:
        image: adminer
        restart: always
        networks:
            - db-network
        depends_on:
            - db
        ports:
          - 7777:8080
        environment:
          ADMINER_DEFAULT_DB_DRIVER: mysql
          ADMINER_DEFAULT_DB_HOST: db
volumes:
    db-data:
networks:
    db-network:
</code>```

You can see that I've got an SQL script mapped into the initdb entrypoint. This is really simple SQL, it simply creates the db: CREATE DATABASE IF NOT EXISTS forum;

Inside the Node container I'm using knex to talk to the database. When I instantiate knex, I also run any outstanding migrations:

```<code>const environment = process.env.ENVIRONMENT || 'development'
const Knex = require('knex');
const knexConfig = require('../knexfile');
const knex = Knex(knexConfig[environment]);

async function init() {
  try {
    return await knex.migrate.latest();
  } catch (error) {
    console.log(error);
  } finally {
    return;
  }
}

init();

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

The problem i'm getting only appears on 'first up' o docker-compose (or more specifically when it needs to create the db-data volume). If I drop the volume docker-compose down -V I get the error when 'up-ing' again. The problem is your classic ECONNREFUSED:

```<code>Creating network "forum_db-network" with the default driver
Creating volume "forum_db-data" with default driver
Creating db ... done
Creating forum_adminer_1 ... done
Creating forum_forum_1   ... done
Attaching to db, forum_adminer_1, forum_forum_1
db         | Initializing database
db         | 2020-02-20T09:50:46.701629Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
db         | 2020-02-20T09:50:47.004757Z 0 [Warning] InnoDB: New log files created, LSN=45790
db         | 2020-02-20T09:50:47.062521Z 0 [Warning] InnoDB: Creating foreign key constraint system tables.
db         | 2020-02-20T09:50:47.122917Z 0 [Warning] No existing UUID has been found, so we assume that this is the first time that this server has been started. Generating a new UUID: 7810f3c2-53c6-11ea-ba00-0242c0a81002.
db         | 2020-02-20T09:50:47.126689Z 0 [Warning] Gtid table is not ready to be used. Table 'mysql.gtid_executed' cannot be opened.
adminer_1  | [Thu Feb 20 09:50:47 2020] PHP 7.4.2 Development Server (http://[::]:8080) started
db         | 2020-02-20T09:50:47.127637Z 1 [Warning] root@localhost is created with an empty password ! Please consider switching off the --initialize-insecure option.
db         | 2020-02-20T09:50:47.955961Z 1 [Warning] 'user' entry 'root@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:47.956454Z 1 [Warning] 'user' entry 'mysql.session@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:47.957026Z 1 [Warning] 'user' entry 'mysql.sys@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:47.957747Z 1 [Warning] 'db' entry 'performance_schema mysql.session@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:47.958212Z 1 [Warning] 'db' entry 'sys mysql.sys@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:47.958797Z 1 [Warning] 'proxies_priv' entry '@ root@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:47.959520Z 1 [Warning] 'tables_priv' entry 'user mysql.session@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:47.960113Z 1 [Warning] 'tables_priv' entry 'sys_config mysql.sys@localhost' ignored in --skip-name-resolve mode.
forum_1    |
forum_1    | > express-oauth-vuex-starter@1.0.0 start /home/node/app
forum_1    | > nodemon index.js
forum_1    |
forum_1    | [nodemon] 2.0.2
forum_1    | [nodemon] to restart at any time, enter `rs`
forum_1    | [nodemon] watching dir(s): *.*
forum_1    | [nodemon] watching extensions: js,mjs,json
forum_1    | [nodemon] starting `node index.js`
db         | Database initialized
db         | Initializing certificates
db         | Generating a RSA private key
db         | ........................................................................................................................+++++
db         | ..........+++++
db         | unable to write 'random state'
db         | writing new private key to 'ca-key.pem'
db         | -----
db         | Generating a RSA private key
db         | .........................................................................................+++++
db         | .............+++++
db         | unable to write 'random state'
db         | writing new private key to 'server-key.pem'
db         | -----
db         | Generating a RSA private key
db         | .....................................................+++++
db         | .+++++
db         | unable to write 'random state'
db         | writing new private key to 'client-key.pem'
db         | -----
db         | Certificates initialized
db         | MySQL init process in progress...
db         | 2020-02-20T09:50:51.037907Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
db         | 2020-02-20T09:50:51.039423Z 0 [Note] mysqld (mysqld 5.7.24) starting as process 89 ...
db         | 2020-02-20T09:50:51.044545Z 0 [Note] InnoDB: PUNCH HOLE support available
db         | 2020-02-20T09:50:51.044653Z 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
db         | 2020-02-20T09:50:51.044701Z 0 [Note] InnoDB: Uses event mutexes
db         | 2020-02-20T09:50:51.044745Z 0 [Note] InnoDB: GCC builtin __atomic_thread_fence() is used for memory barrier
db         | 2020-02-20T09:50:51.044786Z 0 [Note] InnoDB: Compressed tables use zlib 1.2.11
db         | 2020-02-20T09:50:51.044825Z 0 [Note] InnoDB: Using Linux native AIO
db         | 2020-02-20T09:50:51.045705Z 0 [Note] InnoDB: Number of pools: 1
db         | 2020-02-20T09:50:51.046113Z 0 [Note] InnoDB: Using CPU crc32 instructions
db         | 2020-02-20T09:50:51.048701Z 0 [Note] InnoDB: Initializing buffer pool, total size = 128M, instances = 1, chunk size = 128M
db         | 2020-02-20T09:50:51.060691Z 0 [Note] InnoDB: Completed initialization of buffer pool
db         | 2020-02-20T09:50:51.064263Z 0 [Note] InnoDB: If the mysqld execution user is authorized, page cleaner thread priority can be changed. See the man page of setpriority().
db         | 2020-02-20T09:50:51.076676Z 0 [Note] InnoDB: Highest supported file format is Barracuda.
db         | 2020-02-20T09:50:51.097380Z 0 [Note] InnoDB: Creating shared tablespace for temporary tables
db         | 2020-02-20T09:50:51.097533Z 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
db         | 2020-02-20T09:50:51.131620Z 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.
db         | 2020-02-20T09:50:51.134052Z 0 [Note] InnoDB: 96 redo rollback segment(s) found. 96 redo rollback segment(s) are active.
db         | 2020-02-20T09:50:51.134142Z 0 [Note] InnoDB: 32 non-redo rollback segment(s) are active.
db         | 2020-02-20T09:50:51.135177Z 0 [Note] InnoDB: Waiting for purge to start
db         | 2020-02-20T09:50:51.185530Z 0 [Note] InnoDB: 5.7.24 started; log sequence number 2591440
db         | 2020-02-20T09:50:51.186329Z 0 [Note] Plugin 'FEDERATED' is disabled.
db         | 2020-02-20T09:50:51.192075Z 0 [Note] Found ca.pem, server-cert.pem and server-key.pem in data directory. Trying to enable SSL support using them.
db         | 2020-02-20T09:50:51.192591Z 0 [Warning] CA certificate ca.pem is self signed.
db         | 2020-02-20T09:50:51.194602Z 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
db         | 2020-02-20T09:50:51.197793Z 0 [Note] InnoDB: Buffer pool(s) load completed at 200220  9:50:51
db         | 2020-02-20T09:50:51.198483Z 0 [Warning] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
db         | 2020-02-20T09:50:51.200316Z 0 [Warning] 'user' entry 'root@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:51.200460Z 0 [Warning] 'user' entry 'mysql.session@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:51.200532Z 0 [Warning] 'user' entry 'mysql.sys@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:51.200606Z 0 [Warning] 'db' entry 'performance_schema mysql.session@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:51.200656Z 0 [Warning] 'db' entry 'sys mysql.sys@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:51.200717Z 0 [Warning] 'proxies_priv' entry '@ root@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:51.202731Z 0 [Warning] 'tables_priv' entry 'user mysql.session@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:51.202816Z 0 [Warning] 'tables_priv' entry 'sys_config mysql.sys@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:51.219832Z 0 [Note] Event Scheduler: Loaded 0 events
db         | 2020-02-20T09:50:51.221248Z 0 [Note] mysqld: ready for connections.
db         | Version: '5.7.24'  socket: '/var/run/mysqld/mysqld.sock'  port: 0  MySQL Community Server (GPL)
forum_1    | Listening...
forum_1    | Error: connect ECONNREFUSED 192.168.16.2:3306
forum_1    |     at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1137:16)
forum_1    |     at Protocol._enqueue (/home/node/app/node_modules/mysql/lib/protocol/Protocol.js:144:48)
forum_1    |     at Protocol.handshake (/home/node/app/node_modules/mysql/lib/protocol/Protocol.js:51:23)
forum_1    |     at Connection.connect (/home/node/app/node_modules/mysql/lib/Connection.js:116:18)
forum_1    |     at /home/node/app/node_modules/knex/lib/dialects/mysql/index.js:69:18
forum_1    | From previous event:
forum_1    |     at Client_MySQL.acquireRawConnection (/home/node/app/node_modules/knex/lib/dialects/mysql/index.js:64:12)
forum_1    |     at create (/home/node/app/node_modules/knex/lib/client.js:291:39)
forum_1    |     at processTicksAndRejections (internal/process/task_queues.js:97:5) {
forum_1    |   errno: 'ECONNREFUSED',
forum_1    |   code: 'ECONNREFUSED',
forum_1    |   syscall: 'connect',
forum_1    |   address: '192.168.16.2',
forum_1    |   port: 3306,
forum_1    |   fatal: true
forum_1    | }
db         | Warning: Unable to load '/usr/share/zoneinfo/iso3166.tab' as time zone. Skipping it.
db         | Warning: Unable to load '/usr/share/zoneinfo/leap-seconds.list' as time zone. Skipping it.
db         | Warning: Unable to load '/usr/share/zoneinfo/zone.tab' as time zone. Skipping it.
db         | Warning: Unable to load '/usr/share/zoneinfo/zone1970.tab' as time zone. Skipping it.
db         | 2020-02-20T09:50:54.889060Z 4 [Warning] 'user' entry 'root@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:54.889116Z 4 [Warning] 'user' entry 'mysql.session@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:54.889137Z 4 [Warning] 'user' entry 'mysql.sys@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:54.889164Z 4 [Warning] 'db' entry 'performance_schema mysql.session@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:54.889172Z 4 [Warning] 'db' entry 'sys mysql.sys@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:54.889188Z 4 [Warning] 'proxies_priv' entry '@ root@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:54.890011Z 4 [Warning] 'tables_priv' entry 'user mysql.session@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:54.890057Z 4 [Warning] 'tables_priv' entry 'sys_config mysql.sys@localhost' ignored in --skip-name-resolve mode.
db         |
db         | /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/init.sql
db         | mysql: [Warning] Using a password on the command line interface can be insecure.
db         |
db         |
db         | 2020-02-20T09:50:54.915362Z 0 [Note] Giving 0 client threads a chance to die gracefully
db         | 2020-02-20T09:50:54.915705Z 0 [Note] Shutting down slave threads
db         | 2020-02-20T09:50:54.916456Z 0 [Note] Forcefully disconnecting 0 remaining clients
db         | 2020-02-20T09:50:54.917013Z 0 [Note] Event Scheduler: Purging the queue. 0 events
db         | 2020-02-20T09:50:54.917696Z 0 [Note] Binlog end
db         | 2020-02-20T09:50:54.918665Z 0 [Note] Shutting down plugin 'ngram'
db         | 2020-02-20T09:50:54.919138Z 0 [Note] Shutting down plugin 'partition'
db         | 2020-02-20T09:50:54.919357Z 0 [Note] Shutting down plugin 'BLACKHOLE'
db         | 2020-02-20T09:50:54.920107Z 0 [Note] Shutting down plugin 'ARCHIVE'
db         | 2020-02-20T09:50:54.920322Z 0 [Note] Shutting down plugin 'PERFORMANCE_SCHEMA'
db         | 2020-02-20T09:50:54.921325Z 0 [Note] Shutting down plugin 'MRG_MYISAM'
db         | 2020-02-20T09:50:54.921840Z 0 [Note] Shutting down plugin 'MyISAM'
db         | 2020-02-20T09:50:54.922751Z 0 [Note] Shutting down plugin 'INNODB_SYS_VIRTUAL'
db         | 2020-02-20T09:50:54.923300Z 0 [Note] Shutting down plugin 'INNODB_SYS_DATAFILES'
db         | 2020-02-20T09:50:54.923360Z 0 [Note] Shutting down plugin 'INNODB_SYS_TABLESPACES'
db         | 2020-02-20T09:50:54.923589Z 0 [Note] Shutting down plugin 'INNODB_SYS_FOREIGN_COLS'
db         | 2020-02-20T09:50:54.923959Z 0 [Note] Shutting down plugin 'INNODB_SYS_FOREIGN'
db         | 2020-02-20T09:50:54.924112Z 0 [Note] Shutting down plugin 'INNODB_SYS_FIELDS'
db         | 2020-02-20T09:50:54.924269Z 0 [Note] Shutting down plugin 'INNODB_SYS_COLUMNS'
db         | 2020-02-20T09:50:54.924754Z 0 [Note] Shutting down plugin 'INNODB_SYS_INDEXES'
db         | 2020-02-20T09:50:54.925454Z 0 [Note] Shutting down plugin 'INNODB_SYS_TABLESTATS'
db         | 2020-02-20T09:50:54.925535Z 0 [Note] Shutting down plugin 'INNODB_SYS_TABLES'
db         | 2020-02-20T09:50:54.925688Z 0 [Note] Shutting down plugin 'INNODB_FT_INDEX_TABLE'
db         | 2020-02-20T09:50:54.925728Z 0 [Note] Shutting down plugin 'INNODB_FT_INDEX_CACHE'
db         | 2020-02-20T09:50:54.926261Z 0 [Note] Shutting down plugin 'INNODB_FT_CONFIG'
db         | 2020-02-20T09:50:54.926443Z 0 [Note] Shutting down plugin 'INNODB_FT_BEING_DELETED'
db         | 2020-02-20T09:50:54.926836Z 0 [Note] Shutting down plugin 'INNODB_FT_DELETED'
db         | 2020-02-20T09:50:54.927513Z 0 [Note] Shutting down plugin 'INNODB_FT_DEFAULT_STOPWORD'
db         | 2020-02-20T09:50:54.927560Z 0 [Note] Shutting down plugin 'INNODB_METRICS'
db         | 2020-02-20T09:50:54.927718Z 0 [Note] Shutting down plugin 'INNODB_TEMP_TABLE_INFO'
db         | 2020-02-20T09:50:54.927806Z 0 [Note] Shutting down plugin 'INNODB_BUFFER_POOL_STATS'
db         | 2020-02-20T09:50:54.927847Z 0 [Note] Shutting down plugin 'INNODB_BUFFER_PAGE_LRU'
db         | 2020-02-20T09:50:54.928201Z 0 [Note] Shutting down plugin 'INNODB_BUFFER_PAGE'
db         | 2020-02-20T09:50:54.928360Z 0 [Note] Shutting down plugin 'INNODB_CMP_PER_INDEX_RESET'
db         | 2020-02-20T09:50:54.928817Z 0 [Note] Shutting down plugin 'INNODB_CMP_PER_INDEX'
db         | 2020-02-20T09:50:54.929031Z 0 [Note] Shutting down plugin 'INNODB_CMPMEM_RESET'
db         | 2020-02-20T09:50:54.929717Z 0 [Note] Shutting down plugin 'INNODB_CMPMEM'
db         | 2020-02-20T09:50:54.929740Z 0 [Note] Shutting down plugin 'INNODB_CMP_RESET'
db         | 2020-02-20T09:50:54.929898Z 0 [Note] Shutting down plugin 'INNODB_CMP'
db         | 2020-02-20T09:50:54.929912Z 0 [Note] Shutting down plugin 'INNODB_LOCK_WAITS'
db         | 2020-02-20T09:50:54.930509Z 0 [Note] Shutting down plugin 'INNODB_LOCKS'
db         | 2020-02-20T09:50:54.930535Z 0 [Note] Shutting down plugin 'INNODB_TRX'
db         | 2020-02-20T09:50:54.930549Z 0 [Note] Shutting down plugin 'InnoDB'
db         | 2020-02-20T09:50:54.931131Z 0 [Note] InnoDB: FTS optimize thread exiting.
db         | 2020-02-20T09:50:54.931746Z 0 [Note] InnoDB: Starting shutdown...
db         | 2020-02-20T09:50:55.032188Z 0 [Note] InnoDB: Dumping buffer pool(s) to /var/lib/mysql/ib_buffer_pool
db         | 2020-02-20T09:50:55.032448Z 0 [Note] InnoDB: Buffer pool(s) dump completed at 200220  9:50:55
</code>```

If the volume already exists, I get no errors, knex connects and the migrations are run.

In the error log you can see that the Node container starts up directly after mysqld: ready for connections. However, you can see that after the Node error, the db container then runs init.sql. Presumably this means that knex is trying to connect to a specific database before it exists, which I guess could be the cause of the refused connection.

So I guess I'm looking for a way to defer the instantiation of the node container until after the MySQL container has run init.sql. I'm already using the depends_on docker compose property - are there any other docker options available to me?

答:
In the end I solved this by setting the MYSQL_DATABASE environment variable for the MySQL container. From the MySQL image docs:

MYSQL_DATABASE

  This variable is optional and allows you to specify the
  name of a database to be created on image startup. If a user/password
  was supplied (see below) then that user will be granted superuser
  access (corresponding to GRANT ALL) to this database

```<code>db:
    image: mysql:5.7
    command: --default-authentication-plugin=mysql_native_password
    ports:
        - "3306:3306"
    environment:
        MYSQL_DATABASE: forum
        MYSQL_ROOT_PASSWORD: root
    container_name: 'db'
    networks:
        - db-network
    volumes:
        - db-data:/var/lib/mysql
</code>```

In addition to this, I used is-port-reachable to hold initial migrations until the MySQL container is available.

```<code>const isPortReachable = require('is-port-reachable');
const environment = process.env.ENVIRONMENT || 'development'
const Knex = require('knex');
const knexConfig = require('../knexfile');
const knex = Knex(knexConfig[environment]);

async function init() {
  let dbStatus = false;

  while (!dbStatus) {
    dbStatus = await isPortReachable(knexConfig[environment].connection.port, {host: knexConfig[environment].connection.host});
  }

  try {
    return await knex.migrate.latest();
  } catch (error) {
    console.log(error);
  }
}

init();

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

Update

While the above did solve this specific problem, there was a raft of other issues that kept popping up - all to do with MySQL configuration. In the end I got tired of playing whack-a-mole and switched to Postgres (incredibly simple thanks to Knex). Span the image up and everything just worked...

If you are having issues with docker-compose, knex and mysql, my advice would be to just use Postgres!

Body:
I'm trying to build out a NodeJS/MySQL stack, but am experiencing an intermittent issue.

Here is my docker compose file:

version: '3'
services:
    db:
        image: mysql:5.7
        command: --default-authentication-plugin=mysql_native_password
        ports:
            - "3306:3306"
        environment:
            MYSQL_ROOT_PASSWORD: root
        container_name: 'db'
        networks:
            - db-network
        volumes:
            - db-data:/var/lib/mysql
            - ./db:/docker-entrypoint-initdb.d
    forum:
        image: "node:12"
        user: "node"
        working_dir: /home/node/app
        depends_on:
            - db
        ports:
            - 7000:3000
        environment:
          - NODE_ENV=development
          - PORT=3000
        volumes:
          - ./server:/home/node/app
        command: "npm start"
        networks:
            - db-network
    adminer:
        image: adminer
        restart: always
        networks:
            - db-network
        depends_on:
            - db
        ports:
          - 7777:8080
        environment:
          ADMINER_DEFAULT_DB_DRIVER: mysql
          ADMINER_DEFAULT_DB_HOST: db
volumes:
    db-data:
networks:
    db-network:

You can see that I've got an SQL script mapped into the initdb entrypoint. This is really simple SQL, it simply creates the db: CREATE DATABASE IF NOT EXISTS forum;

Inside the Node container I'm using knex to talk to the database. When I instantiate knex, I also run any outstanding migrations:

const environment = process.env.ENVIRONMENT || 'development'
const Knex = require('knex');
const knexConfig = require('../knexfile');
const knex = Knex(knexConfig[environment]);

async function init() {
  try {
    return await knex.migrate.latest();
  } catch (error) {
    console.log(error);
  } finally {
    return;
  }
}

init();

module.exports = knex;

The problem i'm getting only appears on 'first up' o docker-compose (or more specifically when it needs to create the db-data volume). If I drop the volume docker-compose down -V I get the error when 'up-ing' again. The problem is your classic ECONNREFUSED:

Creating network "forum_db-network" with the default driver
Creating volume "forum_db-data" with default driver
Creating db ... done
Creating forum_adminer_1 ... done
Creating forum_forum_1   ... done
Attaching to db, forum_adminer_1, forum_forum_1
db         | Initializing database
db         | 2020-02-20T09:50:46.701629Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
db         | 2020-02-20T09:50:47.004757Z 0 [Warning] InnoDB: New log files created, LSN=45790
db         | 2020-02-20T09:50:47.062521Z 0 [Warning] InnoDB: Creating foreign key constraint system tables.
db         | 2020-02-20T09:50:47.122917Z 0 [Warning] No existing UUID has been found, so we assume that this is the first time that this server has been started. Generating a new UUID: 7810f3c2-53c6-11ea-ba00-0242c0a81002.
db         | 2020-02-20T09:50:47.126689Z 0 [Warning] Gtid table is not ready to be used. Table 'mysql.gtid_executed' cannot be opened.
adminer_1  | [Thu Feb 20 09:50:47 2020] PHP 7.4.2 Development Server (http://[::]:8080) started
db         | 2020-02-20T09:50:47.127637Z 1 [Warning] root@localhost is created with an empty password ! Please consider switching off the --initialize-insecure option.
db         | 2020-02-20T09:50:47.955961Z 1 [Warning] 'user' entry 'root@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:47.956454Z 1 [Warning] 'user' entry 'mysql.session@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:47.957026Z 1 [Warning] 'user' entry 'mysql.sys@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:47.957747Z 1 [Warning] 'db' entry 'performance_schema mysql.session@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:47.958212Z 1 [Warning] 'db' entry 'sys mysql.sys@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:47.958797Z 1 [Warning] 'proxies_priv' entry '@ root@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:47.959520Z 1 [Warning] 'tables_priv' entry 'user mysql.session@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:47.960113Z 1 [Warning] 'tables_priv' entry 'sys_config mysql.sys@localhost' ignored in --skip-name-resolve mode.
forum_1    |
forum_1    | > express-oauth-vuex-starter@1.0.0 start /home/node/app
forum_1    | > nodemon index.js
forum_1    |
forum_1    | [nodemon] 2.0.2
forum_1    | [nodemon] to restart at any time, enter `rs`
forum_1    | [nodemon] watching dir(s): *.*
forum_1    | [nodemon] watching extensions: js,mjs,json
forum_1    | [nodemon] starting `node index.js`
db         | Database initialized
db         | Initializing certificates
db         | Generating a RSA private key
db         | ........................................................................................................................+++++
db         | ..........+++++
db         | unable to write 'random state'
db         | writing new private key to 'ca-key.pem'
db         | -----
db         | Generating a RSA private key
db         | .........................................................................................+++++
db         | .............+++++
db         | unable to write 'random state'
db         | writing new private key to 'server-key.pem'
db         | -----
db         | Generating a RSA private key
db         | .....................................................+++++
db         | .+++++
db         | unable to write 'random state'
db         | writing new private key to 'client-key.pem'
db         | -----
db         | Certificates initialized
db         | MySQL init process in progress...
db         | 2020-02-20T09:50:51.037907Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
db         | 2020-02-20T09:50:51.039423Z 0 [Note] mysqld (mysqld 5.7.24) starting as process 89 ...
db         | 2020-02-20T09:50:51.044545Z 0 [Note] InnoDB: PUNCH HOLE support available
db         | 2020-02-20T09:50:51.044653Z 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
db         | 2020-02-20T09:50:51.044701Z 0 [Note] InnoDB: Uses event mutexes
db         | 2020-02-20T09:50:51.044745Z 0 [Note] InnoDB: GCC builtin __atomic_thread_fence() is used for memory barrier
db         | 2020-02-20T09:50:51.044786Z 0 [Note] InnoDB: Compressed tables use zlib 1.2.11
db         | 2020-02-20T09:50:51.044825Z 0 [Note] InnoDB: Using Linux native AIO
db         | 2020-02-20T09:50:51.045705Z 0 [Note] InnoDB: Number of pools: 1
db         | 2020-02-20T09:50:51.046113Z 0 [Note] InnoDB: Using CPU crc32 instructions
db         | 2020-02-20T09:50:51.048701Z 0 [Note] InnoDB: Initializing buffer pool, total size = 128M, instances = 1, chunk size = 128M
db         | 2020-02-20T09:50:51.060691Z 0 [Note] InnoDB: Completed initialization of buffer pool
db         | 2020-02-20T09:50:51.064263Z 0 [Note] InnoDB: If the mysqld execution user is authorized, page cleaner thread priority can be changed. See the man page of setpriority().
db         | 2020-02-20T09:50:51.076676Z 0 [Note] InnoDB: Highest supported file format is Barracuda.
db         | 2020-02-20T09:50:51.097380Z 0 [Note] InnoDB: Creating shared tablespace for temporary tables
db         | 2020-02-20T09:50:51.097533Z 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
db         | 2020-02-20T09:50:51.131620Z 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.
db         | 2020-02-20T09:50:51.134052Z 0 [Note] InnoDB: 96 redo rollback segment(s) found. 96 redo rollback segment(s) are active.
db         | 2020-02-20T09:50:51.134142Z 0 [Note] InnoDB: 32 non-redo rollback segment(s) are active.
db         | 2020-02-20T09:50:51.135177Z 0 [Note] InnoDB: Waiting for purge to start
db         | 2020-02-20T09:50:51.185530Z 0 [Note] InnoDB: 5.7.24 started; log sequence number 2591440
db         | 2020-02-20T09:50:51.186329Z 0 [Note] Plugin 'FEDERATED' is disabled.
db         | 2020-02-20T09:50:51.192075Z 0 [Note] Found ca.pem, server-cert.pem and server-key.pem in data directory. Trying to enable SSL support using them.
db         | 2020-02-20T09:50:51.192591Z 0 [Warning] CA certificate ca.pem is self signed.
db         | 2020-02-20T09:50:51.194602Z 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
db         | 2020-02-20T09:50:51.197793Z 0 [Note] InnoDB: Buffer pool(s) load completed at 200220  9:50:51
db         | 2020-02-20T09:50:51.198483Z 0 [Warning] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
db         | 2020-02-20T09:50:51.200316Z 0 [Warning] 'user' entry 'root@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:51.200460Z 0 [Warning] 'user' entry 'mysql.session@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:51.200532Z 0 [Warning] 'user' entry 'mysql.sys@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:51.200606Z 0 [Warning] 'db' entry 'performance_schema mysql.session@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:51.200656Z 0 [Warning] 'db' entry 'sys mysql.sys@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:51.200717Z 0 [Warning] 'proxies_priv' entry '@ root@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:51.202731Z 0 [Warning] 'tables_priv' entry 'user mysql.session@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:51.202816Z 0 [Warning] 'tables_priv' entry 'sys_config mysql.sys@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:51.219832Z 0 [Note] Event Scheduler: Loaded 0 events
db         | 2020-02-20T09:50:51.221248Z 0 [Note] mysqld: ready for connections.
db         | Version: '5.7.24'  socket: '/var/run/mysqld/mysqld.sock'  port: 0  MySQL Community Server (GPL)
forum_1    | Listening...
forum_1    | Error: connect ECONNREFUSED 192.168.16.2:3306
forum_1    |     at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1137:16)
forum_1    |     at Protocol._enqueue (/home/node/app/node_modules/mysql/lib/protocol/Protocol.js:144:48)
forum_1    |     at Protocol.handshake (/home/node/app/node_modules/mysql/lib/protocol/Protocol.js:51:23)
forum_1    |     at Connection.connect (/home/node/app/node_modules/mysql/lib/Connection.js:116:18)
forum_1    |     at /home/node/app/node_modules/knex/lib/dialects/mysql/index.js:69:18
forum_1    | From previous event:
forum_1    |     at Client_MySQL.acquireRawConnection (/home/node/app/node_modules/knex/lib/dialects/mysql/index.js:64:12)
forum_1    |     at create (/home/node/app/node_modules/knex/lib/client.js:291:39)
forum_1    |     at processTicksAndRejections (internal/process/task_queues.js:97:5) {
forum_1    |   errno: 'ECONNREFUSED',
forum_1    |   code: 'ECONNREFUSED',
forum_1    |   syscall: 'connect',
forum_1    |   address: '192.168.16.2',
forum_1    |   port: 3306,
forum_1    |   fatal: true
forum_1    | }
db         | Warning: Unable to load '/usr/share/zoneinfo/iso3166.tab' as time zone. Skipping it.
db         | Warning: Unable to load '/usr/share/zoneinfo/leap-seconds.list' as time zone. Skipping it.
db         | Warning: Unable to load '/usr/share/zoneinfo/zone.tab' as time zone. Skipping it.
db         | Warning: Unable to load '/usr/share/zoneinfo/zone1970.tab' as time zone. Skipping it.
db         | 2020-02-20T09:50:54.889060Z 4 [Warning] 'user' entry 'root@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:54.889116Z 4 [Warning] 'user' entry 'mysql.session@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:54.889137Z 4 [Warning] 'user' entry 'mysql.sys@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:54.889164Z 4 [Warning] 'db' entry 'performance_schema mysql.session@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:54.889172Z 4 [Warning] 'db' entry 'sys mysql.sys@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:54.889188Z 4 [Warning] 'proxies_priv' entry '@ root@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:54.890011Z 4 [Warning] 'tables_priv' entry 'user mysql.session@localhost' ignored in --skip-name-resolve mode.
db         | 2020-02-20T09:50:54.890057Z 4 [Warning] 'tables_priv' entry 'sys_config mysql.sys@localhost' ignored in --skip-name-resolve mode.
db         |
db         | /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/init.sql
db         | mysql: [Warning] Using a password on the command line interface can be insecure.
db         |
db         |
db         | 2020-02-20T09:50:54.915362Z 0 [Note] Giving 0 client threads a chance to die gracefully
db         | 2020-02-20T09:50:54.915705Z 0 [Note] Shutting down slave threads
db         | 2020-02-20T09:50:54.916456Z 0 [Note] Forcefully disconnecting 0 remaining clients
db         | 2020-02-20T09:50:54.917013Z 0 [Note] Event Scheduler: Purging the queue. 0 events
db         | 2020-02-20T09:50:54.917696Z 0 [Note] Binlog end
db         | 2020-02-20T09:50:54.918665Z 0 [Note] Shutting down plugin 'ngram'
db         | 2020-02-20T09:50:54.919138Z 0 [Note] Shutting down plugin 'partition'
db         | 2020-02-20T09:50:54.919357Z 0 [Note] Shutting down plugin 'BLACKHOLE'
db         | 2020-02-20T09:50:54.920107Z 0 [Note] Shutting down plugin 'ARCHIVE'
db         | 2020-02-20T09:50:54.920322Z 0 [Note] Shutting down plugin 'PERFORMANCE_SCHEMA'
db         | 2020-02-20T09:50:54.921325Z 0 [Note] Shutting down plugin 'MRG_MYISAM'
db         | 2020-02-20T09:50:54.921840Z 0 [Note] Shutting down plugin 'MyISAM'
db         | 2020-02-20T09:50:54.922751Z 0 [Note] Shutting down plugin 'INNODB_SYS_VIRTUAL'
db         | 2020-02-20T09:50:54.923300Z 0 [Note] Shutting down plugin 'INNODB_SYS_DATAFILES'
db         | 2020-02-20T09:50:54.923360Z 0 [Note] Shutting down plugin 'INNODB_SYS_TABLESPACES'
db         | 2020-02-20T09:50:54.923589Z 0 [Note] Shutting down plugin 'INNODB_SYS_FOREIGN_COLS'
db         | 2020-02-20T09:50:54.923959Z 0 [Note] Shutting down plugin 'INNODB_SYS_FOREIGN'
db         | 2020-02-20T09:50:54.924112Z 0 [Note] Shutting down plugin 'INNODB_SYS_FIELDS'
db         | 2020-02-20T09:50:54.924269Z 0 [Note] Shutting down plugin 'INNODB_SYS_COLUMNS'
db         | 2020-02-20T09:50:54.924754Z 0 [Note] Shutting down plugin 'INNODB_SYS_INDEXES'
db         | 2020-02-20T09:50:54.925454Z 0 [Note] Shutting down plugin 'INNODB_SYS_TABLESTATS'
db         | 2020-02-20T09:50:54.925535Z 0 [Note] Shutting down plugin 'INNODB_SYS_TABLES'
db         | 2020-02-20T09:50:54.925688Z 0 [Note] Shutting down plugin 'INNODB_FT_INDEX_TABLE'
db         | 2020-02-20T09:50:54.925728Z 0 [Note] Shutting down plugin 'INNODB_FT_INDEX_CACHE'
db         | 2020-02-20T09:50:54.926261Z 0 [Note] Shutting down plugin 'INNODB_FT_CONFIG'
db         | 2020-02-20T09:50:54.926443Z 0 [Note] Shutting down plugin 'INNODB_FT_BEING_DELETED'
db         | 2020-02-20T09:50:54.926836Z 0 [Note] Shutting down plugin 'INNODB_FT_DELETED'
db         | 2020-02-20T09:50:54.927513Z 0 [Note] Shutting down plugin 'INNODB_FT_DEFAULT_STOPWORD'
db         | 2020-02-20T09:50:54.927560Z 0 [Note] Shutting down plugin 'INNODB_METRICS'
db         | 2020-02-20T09:50:54.927718Z 0 [Note] Shutting down plugin 'INNODB_TEMP_TABLE_INFO'
db         | 2020-02-20T09:50:54.927806Z 0 [Note] Shutting down plugin 'INNODB_BUFFER_POOL_STATS'
db         | 2020-02-20T09:50:54.927847Z 0 [Note] Shutting down plugin 'INNODB_BUFFER_PAGE_LRU'
db         | 2020-02-20T09:50:54.928201Z 0 [Note] Shutting down plugin 'INNODB_BUFFER_PAGE'
db         | 2020-02-20T09:50:54.928360Z 0 [Note] Shutting down plugin 'INNODB_CMP_PER_INDEX_RESET'
db         | 2020-02-20T09:50:54.928817Z 0 [Note] Shutting down plugin 'INNODB_CMP_PER_INDEX'
db         | 2020-02-20T09:50:54.929031Z 0 [Note] Shutting down plugin 'INNODB_CMPMEM_RESET'
db         | 2020-02-20T09:50:54.929717Z 0 [Note] Shutting down plugin 'INNODB_CMPMEM'
db         | 2020-02-20T09:50:54.929740Z 0 [Note] Shutting down plugin 'INNODB_CMP_RESET'
db         | 2020-02-20T09:50:54.929898Z 0 [Note] Shutting down plugin 'INNODB_CMP'
db         | 2020-02-20T09:50:54.929912Z 0 [Note] Shutting down plugin 'INNODB_LOCK_WAITS'
db         | 2020-02-20T09:50:54.930509Z 0 [Note] Shutting down plugin 'INNODB_LOCKS'
db         | 2020-02-20T09:50:54.930535Z 0 [Note] Shutting down plugin 'INNODB_TRX'
db         | 2020-02-20T09:50:54.930549Z 0 [Note] Shutting down plugin 'InnoDB'
db         | 2020-02-20T09:50:54.931131Z 0 [Note] InnoDB: FTS optimize thread exiting.
db         | 2020-02-20T09:50:54.931746Z 0 [Note] InnoDB: Starting shutdown...
db         | 2020-02-20T09:50:55.032188Z 0 [Note] InnoDB: Dumping buffer pool(s) to /var/lib/mysql/ib_buffer_pool
db         | 2020-02-20T09:50:55.032448Z 0 [Note] InnoDB: Buffer pool(s) dump completed at 200220  9:50:55

If the volume already exists, I get no errors, knex connects and the migrations are run.

In the error log you can see that the Node container starts up directly after mysqld: ready for connections. However, you can see that after the Node error, the db container then runs init.sql. Presumably this means that knex is trying to connect to a specific database before it exists, which I guess could be the cause of the refused connection.

So I guess I'm looking for a way to defer the instantiation of the node container until after the MySQL container has run init.sql. I'm already using the depends_on docker compose property - are there any other docker options available to me?

Body:
In the end I solved this by setting the MYSQL_DATABASE environment variable for the MySQL container. From the MySQL image docs:

MYSQL_DATABASE

  This variable is optional and allows you to specify the
  name of a database to be created on image startup. If a user/password
  was supplied (see below) then that user will be granted superuser
  access (corresponding to GRANT ALL) to this database

db:
    image: mysql:5.7
    command: --default-authentication-plugin=mysql_native_password
    ports:
        - "3306:3306"
    environment:
        MYSQL_DATABASE: forum
        MYSQL_ROOT_PASSWORD: root
    container_name: 'db'
    networks:
        - db-network
    volumes:
        - db-data:/var/lib/mysql

In addition to this, I used is-port-reachable to hold initial migrations until the MySQL container is available.

const isPortReachable = require('is-port-reachable');
const environment = process.env.ENVIRONMENT || 'development'
const Knex = require('knex');
const knexConfig = require('../knexfile');
const knex = Knex(knexConfig[environment]);

async function init() {
  let dbStatus = false;

  while (!dbStatus) {
    dbStatus = await isPortReachable(knexConfig[environment].connection.port, {host: knexConfig[environment].connection.host});
  }

  try {
    return await knex.migrate.latest();
  } catch (error) {
    console.log(error);
  }
}

init();

module.exports = knex;

Update

While the above did solve this specific problem, there was a raft of other issues that kept popping up - all to do with MySQL configuration. In the end I got tired of playing whack-a-mole and switched to Postgres (incredibly simple thanks to Knex). Span the image up and everything just worked...

If you are having issues with docker-compose, knex and mysql, my advice would be to just use Postgres!


问:
How to implement Update subquery in sql server 2017 I want to update one column using multiple select but its showing subquery error
```<code>UPDATE temp_hourly_stats SET peak_location_percentage =(
(SELECT TOP(1) peak_location_count as peak_location_count FROM temp_hourly_stats where time_range = (select concat( DATEPART(hh, DATEADD(hh,-1,CURRENT_TIMESTAMP)) ,'-', DATEPART(hh, CURRENT_TIMESTAMP))as time_range) order by id desc)UNION
(SELECT TOP(1) total_count as total_count FROM temp_hourly_stats where time_range = (select concat( DATEPART(hh, DATEADD(hh,-1,CURRENT_TIMESTAMP)) ,'-', DATEPART(hh, CURRENT_TIMESTAMP))as time_range) order by id desc)Union
(select (peak_location_count*100)/total_count as peak_loc_percentage))
</code>```

The error I am getting is this:-
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.

答:
Your subquery has 2 UNION's, so your it returns 3 records. So thats the reason you are getting the error. There are a couple of ways to handle your request.
Try something like this:</p>

```<code>  UPDATE temp_hourly_stats
SET         temp_hourly_stats.peak_location_percentage = ( CA1.peak_location_count * 100 ) / CA2.total_count
FROM        temp_hourly_stats
CROSS APPLY
            (
                     SELECT TOP(1)
                              peak_location_count AS peak_location_count
                     FROM     temp_hourly_stats
                     WHERE    time_range =
                              (
                                     SELECT concat( Datepart(hh, Dateadd(hh,-1,CURRENT_TIMESTAMP)) ,'-', Datepart(hh, CURRENT_TIMESTAMP))AS time_range)
                     ORDER BY id DESC ) AS CA1
CROSS APPLY
            (
                     SELECT TOP(1)
                              total_count AS total_count
                     FROM     temp_hourly_stats
                     WHERE    time_range =
                              (
                                     SELECT concat( Datepart(hh, Dateadd(hh,-1,CURRENT_TIMESTAMP)) ,'-', Datepart(hh, CURRENT_TIMESTAMP))AS time_range)
                     ORDER BY id DESC ) AS CA2
</code>```

Body:
UPDATE temp_hourly_stats SET peak_location_percentage =(
(SELECT TOP(1) peak_location_count as peak_location_count FROM temp_hourly_stats where time_range = (select concat( DATEPART(hh, DATEADD(hh,-1,CURRENT_TIMESTAMP)) ,'-', DATEPART(hh, CURRENT_TIMESTAMP))as time_range) order by id desc)UNION
(SELECT TOP(1) total_count as total_count FROM temp_hourly_stats where time_range = (select concat( DATEPART(hh, DATEADD(hh,-1,CURRENT_TIMESTAMP)) ,'-', DATEPART(hh, CURRENT_TIMESTAMP))as time_range) order by id desc)Union
(select (peak_location_count*100)/total_count as peak_loc_percentage))

The error I am getting is this:-
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.

Body:
Your subquery has 2 UNION's, so your it returns 3 records. So thats the reason you are getting the error. There are a couple of ways to handle your request.
Try something like this:

  UPDATE temp_hourly_stats
SET         temp_hourly_stats.peak_location_percentage = ( CA1.peak_location_count * 100 ) / CA2.total_count
FROM        temp_hourly_stats
CROSS APPLY
            (
                     SELECT TOP(1)
                              peak_location_count AS peak_location_count
                     FROM     temp_hourly_stats
                     WHERE    time_range =
                              (
                                     SELECT concat( Datepart(hh, Dateadd(hh,-1,CURRENT_TIMESTAMP)) ,'-', Datepart(hh, CURRENT_TIMESTAMP))AS time_range)
                     ORDER BY id DESC ) AS CA1
CROSS APPLY
            (
                     SELECT TOP(1)
                              total_count AS total_count
                     FROM     temp_hourly_stats
                     WHERE    time_range =
                              (
                                     SELECT concat( Datepart(hh, Dateadd(hh,-1,CURRENT_TIMESTAMP)) ,'-', Datepart(hh, CURRENT_TIMESTAMP))AS time_range)
                     ORDER BY id DESC ) AS CA2


问:
Compare a list of strings with each other in R
I am trying to compare a list of strings with each other using the function levenshteinSim() from package 'RecordLinkage'. However, I am having a very hard time to figure out how I can incorporate my list of strings into the function as it only takes two arguments str1 and str2. I am trying to find the most optimal way as my list contains 4k strings. Any help is much appreciated!

Below is some sample data:

```<code>sample <- c('apple', 'appeal', 'apparel', 'peel', 'peer', 'pear')
</code>```

答:
Here is a base R solution to obtain the distance matrix

```<code>z <- Map(utf8ToInt,sample)
dmat <- outer(z,z,FUN = Vectorize(function(x,y) sum(bitwXor(x,y)>0)))
</code>```

such that

```<code>> dmat
        apple appeal apparel peel peer pear
apple       0      3       4    4    5    5
appeal      3      0       4    6    6    6
apparel     4      4       0    6    6    6
peel        4      6       6    0    1    2
peer        5      6       6    1    0    1
pear        5      6       6    2    1    0
</code>```

Body:
I am trying to compare a list of strings with each other using the function levenshteinSim() from package 'RecordLinkage'. However, I am having a very hard time to figure out how I can incorporate my list of strings into the function as it only takes two arguments str1 and str2. I am trying to find the most optimal way as my list contains 4k strings. Any help is much appreciated!

Below is some sample data:

sample <- c('apple', 'appeal', 'apparel', 'peel', 'peer', 'pear')

Body:
Here is a base R solution to obtain the distance matrix

z <- Map(utf8ToInt,sample)
dmat <- outer(z,z,FUN = Vectorize(function(x,y) sum(bitwXor(x,y)>0)))

such that

> dmat
        apple appeal apparel peel peer pear
apple       0      3       4    4    5    5
appeal      3      0       4    6    6    6
apparel     4      4       0    6    6    6
peel        4      6       6    0    1    2
peer        5      6       6    1    0    1
pear        5      6       6    2    1    0


问:
Return error message if input is not string
I'm trying to build an app that asks for input twice. First an integer after a string.

I want it to return an error message once the user inputs an integer for a string intended input and vice versa. I got through with returning an error message if the user inputs a string when it asks for an integer, but I'm having troubles returning an error message if the user inputs an integer when the code asks for a string.

Here's my code so far:

```<code>do {
    System.out.print("Input account number : ");
    input = s.nextLine();
}

while (!isDigit(input));
int acct = Integer.parseInt(input);

System.out.print("Input account name : ");
String name = s.nextLine();
</code>```

答:
For the numeric value you could just try to convert it to an int. For the alphabetic characters only, I would use a simple regex matcher ^[A-Za-z]+$.

Example:

import java.util.Scanner;
import java.util.regex.Pattern;

public class InputDemo {

    private static final Pattern CHARS = Pattern.compile("^[A-Za-z]+$");

    private final Scanner in = new Scanner(System.in);

    public static void main(String[] args) {
        final InputDemo demo = new InputDemo();
        final int accountNumber = demo.readInteger("Input account number: ");
        final String accountName = demo.readAlpha("Input account name: ");

    }

    private int readInteger(String prompt) {
        while (true) {
            try {
                System.out.println(prompt);
                return Integer.parseInt(in.nextLine());
            } catch (NumberFormatException e) {
                System.out.println("Wrong input!");
            }
        }
    }

    private String readAlpha(String prompt) {
        while(true) {
            System.out.println(prompt);
            final String input = in.nextLine();
            if (CHARS.matcher(input).matches()) {
                return input;
            }
            System.out.println("Wrong input!");
        }
    }
}
```

Body:
I'm trying to build an app that asks for input twice. First an integer after a string.

I want it to return an error message once the user inputs an integer for a string intended input and vice versa. I got through with returning an error message if the user inputs a string when it asks for an integer, but I'm having troubles returning an error message if the user inputs an integer when the code asks for a string.

Here's my code so far:

do {
    System.out.print("Input account number : ");
    input = s.nextLine();
}

while (!isDigit(input));
int acct = Integer.parseInt(input);

System.out.print("Input account name : ");
String name = s.nextLine();


问:
Replacing an exact character in a string out of a file?
I'm making a program that fixes a separator in csv file, and my idea was read all the lines, then check each line for the wrong separator, then replace it with the good one. I've been trying multiple things, but this is where I'm stuck right now. This is the code:

```<code>try (FileWriter escritor = new FileWriter(archivoRes.getAbsoluteFile()); BufferedReader lectorArchivo = new BufferedReader(new FileReader(archivoSelec)); BufferedWriter bfw = new BufferedWriter(escritor)) {

    byte[] byteArray = new byte[(int) archivoSelec.length()];
    FileInputStream fis = new FileInputStream(archivoSelec);
    fis.read(byteArray);

    int count = 1;
    for (int i = byteArray.length; i >= 0; i--) {
        String line = lectorArchivo.readLine();
        if (line.indexOf(":") == 82 || line.indexOf(":") == 68 || line.indexOf(":") == 81) {
            line.replaceFirst(":", ";");

        }
        bfw.write(line);
        bfw.newLine();
    }

    bfw.close();

} catch (IOException e) {
    System.err.format("IOException: %s%n", e);
}
</code>```

Any ideas on how I could get this through?

UPDATE:

I've discovered StringTokenizer, which seems easier, but I can't still get it working. This is the code at the moment.

```<code>for(int i = byteArray.length;i >= 0;i--){
                    String line = lectorArchivo.readLine();
                    StringTokenizer token = new StringTokenizer(line, ";");

                    if (token.countTokens() == 3) {
                        line.replaceAll(separador_old, separador);

                    }
                    bfw.write(line);
                    bfw.newLine();

                }

                bfw.close();
</code>```

答:
String is immutable.

line.replaceFirst(":", ";"); does not do anything.

You need to assign the result somewhere.

Maybe back to line?

Body:
I'm making a program that fixes a separator in csv file, and my idea was read all the lines, then check each line for the wrong separator, then replace it with the good one. I've been trying multiple things, but this is where I'm stuck right now. This is the code:

try (FileWriter escritor = new FileWriter(archivoRes.getAbsoluteFile()); BufferedReader lectorArchivo = new BufferedReader(new FileReader(archivoSelec)); BufferedWriter bfw = new BufferedWriter(escritor)) {

    byte[] byteArray = new byte[(int) archivoSelec.length()];
    FileInputStream fis = new FileInputStream(archivoSelec);
    fis.read(byteArray);

    int count = 1;
    for (int i = byteArray.length; i >= 0; i--) {
        String line = lectorArchivo.readLine();
        if (line.indexOf(":") == 82 || line.indexOf(":") == 68 || line.indexOf(":") == 81) {
            line.replaceFirst(":", ";");

        }
        bfw.write(line);
        bfw.newLine();
    }

    bfw.close();

} catch (IOException e) {
    System.err.format("IOException: %s%n", e);
}

Any ideas on how I could get this through?

UPDATE:

I've discovered StringTokenizer, which seems easier, but I can't still get it working. This is the code at the moment.

for(int i = byteArray.length;i >= 0;i--){
                    String line = lectorArchivo.readLine();
                    StringTokenizer token = new StringTokenizer(line, ";");

                    if (token.countTokens() == 3) {
                        line.replaceAll(separador_old, separador);

                    }
                    bfw.write(line);
                    bfw.newLine();

                }

                bfw.close();


问:
Multiple lines in UITabBarItem Label
I've tried many things but impossible to find a way to put the label of a UITabBarItem with a lineNumber customised.0 (i would like to get the title on 2 lines).

Is there a way to do it?

答:
this is my solution for that

we need to implement this inside viewwillLayoutSubviews. to update the ui and make it works

in this example in going to customize my 3rd tab bar item only

```<code>override func viewWillLayoutSubviews() {
    // acess to list of tab bar items
    if let items = self.tabBar.items {
        // in each item we have a view where we find 2 subviews imageview and label
        // in this example i would like to change
        // access to item view
        let viewTabBar = items[2].value(forKey: "view") as? UIView
        // access to item subviews : imageview and label
        if viewTabBar.subviews.count == 2 {
            let label = viewTabBar?.subviews[1]as? UILabel
            // here is the customization for my label 2 lines
            label?.numberOfLines = 2
            label?.textAlignment = .center
            label!.text = "tab_point".localized
            // here customisation for image insets top and bottom
            items[2].imageInsets = UIEdgeInsets(top: 8, left: 0, bottom: -5, right: 0)
        }
    }
}
</code>```

and here is the result

Title: Multiple lines in UITabBarItem Label

Body:
this is my solution for that

we need to implement this inside viewwillLayoutSubviews. to update the ui and make it works

in this example in going to customize my 3rd tab bar item only

override func viewWillLayoutSubviews() {
    // acess to list of tab bar items
    if let items = self.tabBar.items {
        // in each item we have a view where we find 2 subviews imageview and label
        // in this example i would like to change
        // access to item view
        let viewTabBar = items[2].value(forKey: "view") as? UIView
        // access to item subviews : imageview and label
        if viewTabBar.subviews.count == 2 {
            let label = viewTabBar?.subviews[1]as? UILabel
            // here is the customization for my label 2 lines
            label?.numberOfLines = 2
            label?.textAlignment = .center
            label!.text = "tab_point".localized
            // here customisation for image insets top and bottom
            items[2].imageInsets = UIEdgeInsets(top: 8, left: 0, bottom: -5, right: 0)
        }
    }
}

and here is the result


问:
How to make code wait for okay/cancel button selection?
I am using JQuery's $.dialog(), where I open a dialog with OK and Cancel buttons.

I would have expected that when the dialog opens, the code stops, and would first continue, when the user had selected OK or Cancel.

Here is my complete source code
http://pastebin.com/uw7bvtn7

The section where I have the problem is at line 127-151.

```<code>$("#dialog:ui-dialog").dialog("destroy");

$("#dialog-confirm").dialog({
    resizable: false,
    height: 600,
    modal: true,
    open: function() {
    $(this).children('div.dialog-text').replaceWith("<h3><b>Users</b></h3>" + makeDialogTable(users) + "<h3><b>Owners</b></h3>" + makeDialogTable(owners));
    },

    buttons: {
    "Okay": function() {
        $(this).dialog("close");
    },

    Cancel: function() {
        is_okay = 0;
        $(this).dialog("close");
    }
    } // buttons

}); // dialog

alert(is_okay);
</code>```

What the code does right now is to first show the dialog and then the alert(is_okay) on top.

What I would like is that the code first continues when the user have pressed OK or Cancel.

How could that be done?

答:
There is no direct way to "wait" for something in JavaScript -- asynchronous events are generally handled through callbacks. This means you need to think of your program in terms of events and not as sequential code. Instead of your current code:

```<code>$("#dialog-confirm").dialog({
  ...
});

alert(is_okay);
// rest of code
</code>```

you need to wrap the "rest of code" section into its own function, then call that from the OK/Cancel callbacks of your dialog:

```<code>$("#dialog-confirm").dialog({
    ...

    buttons: {
    "Okay": function() {
        $(this).dialog("close");
        what_happens_if_okay();
    },

    Cancel: function() {
        $(this).dialog("close");
        what_happens_if_not_okay();
    }
    } // buttons

}); // dialog
</code>```

Body:
I am using JQuery's $.dialog(), where I open a dialog with OK and Cancel buttons.

I would have expected that when the dialog opens, the code stops, and would first continue, when the user had selected OK or Cancel.

Here is my complete source code
http://pastebin.com/uw7bvtn7

The section where I have the problem is at line 127-151.

$("#dialog:ui-dialog").dialog("destroy");

$("#dialog-confirm").dialog({
    resizable: false,
    height: 600,
    modal: true,
    open: function() {
    $(this).children('div.dialog-text').replaceWith("
Users
" + makeDialogTable(users) + "
Owners
" + makeDialogTable(owners));
    },

    buttons: {
    "Okay": function() {
        $(this).dialog("close");
    },

    Cancel: function() {
        is_okay = 0;
        $(this).dialog("close");
    }
    } // buttons

}); // dialog

alert(is_okay);

What the code does right now is to first show the dialog and then the alert(is_okay) on top.

What I would like is that the code first continues when the user have pressed OK or Cancel.

How could that be done?

Body:
There is no direct way to "wait" for something in JavaScript -- asynchronous events are generally handled through callbacks. This means you need to think of your program in terms of events and not as sequential code. Instead of your current code:

$("#dialog-confirm").dialog({
  ...
});

alert(is_okay);
// rest of code

you need to wrap the "rest of code" section into its own function, then call that from the OK/Cancel callbacks of your dialog:

$("#dialog-confirm").dialog({
    ...

    buttons: {
    "Okay": function() {
        $(this).dialog("close");
        what_happens_if_okay();
    },

    Cancel: function() {
        $(this).dialog("close");
        what_happens_if_not_okay();
    }
    } // buttons

}); // dialog


问:
PLA 1.2 The seller and company names associated with your app do not reflect the name, “Lumique,” in the app or its metadata, as required
Your app must be published under a seller name and company name that reflects the Lumique brand. If you have developed these apps on behalf of a client, please advise your client to add you to the development team of their Apple Developer account.</p>

答:
Once again i got this rejection again, Let me explain how i had fixed this issue.

I scheduled a call with review team and explain about my product
  authority and agreement i.e There is not copyright issue with that. I
  have also send a soft copy of agreement about my app after 2 days my
  app had been lived on appstore.


问:
Count occurrences per data.table row
I have a data.table too large to melt/cast in RAM (millions of rows).

From that I need to extract the rows that do not have duplicate values per row. Duplicate zeros and NA are ok to keep.

In this MWE, the "Duplicates"-column is what I want to calculate.

```<code>DT <- data.table(C1=c(0L, 7L, 0L, 0L),
                 C2=c(0L, 0L, 0L, 4L),
                 C3=c(2L, 0L, 2L, 3L),
                 C4=c(0L, NA_integer_, 2L, 6L),
                 C5=c(1L, 3L, 1L, 1L),
                 c6=c(0L, 4L, 2L, 4L),
                 Duplicates=c(FALSE, FALSE, TRUE, TRUE))

DT.wanted <- DT[Duplicates==FALSE, ]
</code>```

Number of columns vary.

Edit: Here is a for-loop example. Is way too slow.

```<code>DT <- data.table(C1=c(0L, 7L, 0L, 0L),
                 C2=c(0L, 0L, 0L, 4L),
                 C3=c(2L, 0L, 2L, 3L),
                 C4=c(0L, NA_integer_, 2L, 6L),
                 C5=c(1L, 3L, 1L, 1L),
                 c6=c(0L, 4L, 2L, 4L))
DT[, Duplicates:=FALSE]
for (i in 1L:nrow(DT)){
  dt.i <- data.table(table(as.integer(DT[i, ])))
  if (max(dt.i[V1>0, N])>1) DT[i, Duplicates:=TRUE]
}
</code>```

答:
Here is a solution, that should still be slightly faster (~3x).

```<code>foo_dup <- function(x) {
  anyDuplicated(x[!is.na(x) & x != 0L]) != 0L
}

cols <- paste0("C", 1:6)
for (i in 1L:nrow(DT)) {
  set(DT, i, "Duplicates", foo_dup(unlist(DT[i, cols])) )
}

DT
   C1 C2 C3 C4 C5 C6 Duplicates
1:  0  0  2  0  1  0      FALSE
2:  7  0  0 NA  3  4      FALSE
3:  0  0  2  2  1  2       TRUE
4:  0  4  3  6  1  4       TRUE
</code>```

PS. I changed the example data names, c6 to C6.

Title: Count occurrences per data.table row

Body:
I have a data.table too large to melt/cast in RAM (millions of rows).

From that I need to extract the rows that do not have duplicate values per row. Duplicate zeros and NA are ok to keep.

In this MWE, the "Duplicates"-column is what I want to calculate.

DT <- data.table(C1=c(0L, 7L, 0L, 0L),
                 C2=c(0L, 0L, 0L, 4L),
                 C3=c(2L, 0L, 2L, 3L),
                 C4=c(0L, NA_integer_, 2L, 6L),
                 C5=c(1L, 3L, 1L, 1L),
                 c6=c(0L, 4L, 2L, 4L),
                 Duplicates=c(FALSE, FALSE, TRUE, TRUE))

DT.wanted <- DT[Duplicates==FALSE, ]

Number of columns vary.

Edit: Here is a for-loop example. Is way too slow.

DT <- data.table(C1=c(0L, 7L, 0L, 0L),
                 C2=c(0L, 0L, 0L, 4L),
                 C3=c(2L, 0L, 2L, 3L),
                 C4=c(0L, NA_integer_, 2L, 6L),
                 C5=c(1L, 3L, 1L, 1L),
                 c6=c(0L, 4L, 2L, 4L))
DT[, Duplicates:=FALSE]
for (i in 1L:nrow(DT)){
  dt.i <- data.table(table(as.integer(DT[i, ])))
  if (max(dt.i[V1>0, N])>1) DT[i, Duplicates:=TRUE]
}

Body:
Here is a solution, that should still be slightly faster (~3x).

foo_dup <- function(x) {
  anyDuplicated(x[!is.na(x) & x != 0L]) != 0L
}

cols <- paste0("C", 1:6)
for (i in 1L:nrow(DT)) {
  set(DT, i, "Duplicates", foo_dup(unlist(DT[i, cols])) )
}

DT
   C1 C2 C3 C4 C5 C6 Duplicates
1:  0  0  2  0  1  0      FALSE
2:  7  0  0 NA  3  4      FALSE
3:  0  0  2  2  1  2       TRUE
4:  0  4  3  6  1  4       TRUE

PS. I changed the example data names, c6 to C6.