问:
Sending byte array of approximately fixed size everytime to another method
I have a method which takes a parameter which is Partition enum. This method will be called by multiple background threads (15 max) around same time period by passing different value of partition. Here dataHoldersByPartition is a ImmutableMap of Partition and ConcurrentLinkedQueue<DataHolder>.

```<code>  private final ImmutableMap<Partition, ConcurrentLinkedQueue<DataHolder>> dataHoldersByPartition;

  //... some code to populate entry in `dataHoldersByPartition` map

  private void validateAndSend(final Partition partition) {
    ConcurrentLinkedQueue<DataHolder> dataHolders = dataHoldersByPartition.get(partition);
    Map<byte[], byte[]> clientKeyBytesAndProcessBytesHolder = new HashMap<>();
    int totalSize = 0;
    DataHolder dataHolder;
    while ((dataHolder = dataHolders.poll())  != null) {
      byte[] clientKeyBytes = dataHolder.getClientKey().getBytes(StandardCharsets.UTF_8);
      if (clientKeyBytes.length > 255)
        continue;

      byte[] processBytes = dataHolder.getProcessBytes();
      int clientKeyLength = clientKeyBytes.length;
      int processBytesLength = processBytes.length;

      int additionalLength = clientKeyLength + processBytesLength;
      if (totalSize + additionalLength > 50000) {
        Message message = new Message(clientKeyBytesAndProcessBytesHolder, partition);
        // here size of `message.serialize()` byte array should always be less than 50k at all cost
        sendToDatabase(message.getAddress(), message.serialize());
        clientKeyBytesAndProcessBytesHolder = new HashMap<>();
        totalSize = 0;
      }
      clientKeyBytesAndProcessBytesHolder.put(clientKeyBytes, processBytes);
      totalSize += additionalLength;
    }
    // calling again with remaining values only if clientKeyBytesAndProcessBytesHolder is not empty
    if(!clientKeyBytesAndProcessBytesHolder.isEmpty()) {
        Message message = new Message(partition, clientKeyBytesAndProcessBytesHolder);
        // here size of `message.serialize()` byte array should always be less than 50k at all cost
        sendToDatabase(message.getAddress(), message.serialize());
    }
  }
</code>```

And below is my Message class:

```<code>public final class Message {
  private final byte dataCenter;
  private final byte recordVersion;
  private final Map<byte[], byte[]> clientKeyBytesAndProcessBytesHolder;
  private final long address;
  private final long addressFrom;
  private final long addressOrigin;
  private final byte recordsPartition;
  private final byte replicated;

  public Message(Map<byte[], byte[]> clientKeyBytesAndProcessBytesHolder, Partition recordPartition) {
    this.clientKeyBytesAndProcessBytesHolder = clientKeyBytesAndProcessBytesHolder;
    this.recordsPartition = (byte) recordPartition.getPartition();
    this.dataCenter = Utils.CURRENT_LOCATION.get().datacenter();
    this.recordVersion = 1;
    this.replicated = 0;
    long packedAddress = new Data().packAddress();
    this.address = packedAddress;
    this.addressFrom = 0L;
    this.addressOrigin = packedAddress;
  }

  // Output of this method should always be less than 50k always
  public byte[] serialize() {
    // 36 + dataSize + 1 + 1 + keyLength + 8 + 2;
    int bufferCapacity = getBufferCapacity(clientKeyBytesAndProcessBytesHolder);

    ByteBuffer byteBuffer = ByteBuffer.allocate(bufferCapacity).order(ByteOrder.BIG_ENDIAN);
    // header layout
    byteBuffer.put(dataCenter).put(recordVersion).putInt(clientKeyBytesAndProcessBytesHolder.size())
        .putInt(bufferCapacity).putLong(address).putLong(addressFrom).putLong(addressOrigin)
        .put(recordsPartition).put(replicated);

    // data layout
    for (Map.Entry<byte[], byte[]> entry : clientKeyBytesAndProcessBytesHolder.entrySet()) {
      byte keyType = 0;
      byte[] key = entry.getKey();
      byte[] value = entry.getValue();
      byte keyLength = (byte) key.length;
      short valueLength = (short) value.length;

      ByteBuffer dataBuffer = ByteBuffer.wrap(value);
      long timestamp = valueLength > 10 ? dataBuffer.getLong(2) : System.currentTimeMillis();

      byteBuffer.put(keyType).put(keyLength).put(key).putLong(timestamp).putShort(valueLength)
          .put(value);
    }
    return byteBuffer.array();
  }

  private int getBufferCapacity(Map<byte[], byte[]> clientKeyBytesAndProcessBytesHolder) {
    int size = 36;
    for (Entry<byte[], byte[]> entry : clientKeyBytesAndProcessBytesHolder.entrySet()) {
      size += 1 + 1 + 8 + 2;
      size += entry.getKey().length;
      size += entry.getValue().length;
    }
    return size;
  }

    // getters and to string method here
}
</code>```

Basically, what I have to make sure is whenever the sendToDatabase method is called in validateAndSend method, size of message.serialize() byte array should always be less than 50k at all cost. My sendToDatabase method sends byte array coming out from serialize method. So for example if I have 60k records in dataHolders CLQ then I will send in two chunks in validateAndSend method:

First, I will make a byte array  which is approx less than 50k (meaning byte array coming out from message.serialize() is less than 50k) and call sendToDatabase method on it.

Second, I will call sendToDatabase method for remianing part.

And to accomplish above things, I was having totalSize variable in validateAndSend method which is trying to measure 50k size but looks like my approach might not be right and I maybe dropping some records or sending more than 50k everytime I guess?

Looks like my Message class knows about clientKeyBytesAndProcessBytesHolder map and I can use this map to accurately define the size by calling getBufferCapacity method and if is approx less than 50k then call sendToDatabase method?

答:
You might get cleaner code by sorting responsibilities.
Currently, Message class is responsible for converting DataHolder items into a serialized form. But also t is expected to ensure size restriction is fulfilled. Unfortunately, the calling method is checking the size expectations without knowing anything about the size requirements of Message class.

I suggest putting responsibility on sending out proper junks of data to the Message class and thus remove the "knowledge about the proper data junk formatting" to the Message class itself.

You might also have noticed that current implementation is accounting for a full header size per item, while a header is only added once per serialize()

Please find below a sketch of a suggested improvement. The code would need further polishing. But it is primarily intended for illustrating elementary improvements on structure and readability/maintainability.

For isolating the sendToDatabase() functionality from Message class I just added a simple interface:

```<code>// decoupling the sending logic from the formatting
// if external requirements suggest linking such functionality into the message class
// such interface would be unnecessary
public interface DatabaseDelivery {
    void sendToDatabase(long addres, byte[] messagePayload);
}
</code>```

The message class is changed to dealing with junking and size restrictions. It is now Closeable indicating you should call close() finally. (So you might consider using proper constructs with current versions of java)

```<code>public final class Message implements Closeable {
    // or initialize it from some external source if this might change dynamically
    private static final int MAX_SIZE = 50000;
    // better determine this in sync with addHeader() method
    private static final int HEADER_SIZE = 36;

    private final byte dataCenter;
    private final byte recordVersion;
    private final long address;
    private final long addressFrom;
    private final long addressOrigin;
    private final byte recordsPartition;
    private final byte replicated;
    private final DatabaseDelivery delivery;
    private final ByteBuffer itemBuffer = ByteBuffer.allocate(MAX_SIZE);
    private int pendingItems = 0;

    public Message(final Partition recordPartition, final DatabaseDelivery databaseDelivery) {
        this.recordsPartition = (byte) recordPartition.getPartition();
        this.dataCenter = Utils.CURRENT_LOCATION.get().datacenter();
        this.recordVersion = 1;
        this.replicated = 0;
        final long packedAddress = new Data().packAddress();
        this.address = packedAddress;
        this.addressFrom = 0L;
        this.addressOrigin = packedAddress;
        this.delivery = databaseDelivery;
    }

    private void addHeader(final ByteBuffer buffer, final int items) {
        buffer.put(dataCenter)
              .put(recordVersion)
              .putInt(items)
              .putInt(buffer.capacity())
              .putLong(address)
              .putLong(addressFrom)
              .putLong(addressOrigin)
              .put(recordsPartition)
              .put(replicated);
    }

    private void sendData() {
        if (itemBuffer.position() == 0) {
            // no data to be sent
            //Properties: itemBuffer serialized size == 0
            return;
        }
        final ByteBuffer buffer = ByteBuffer.allocate(MAX_SIZE);
        addHeader(buffer, pendingItems);
        itembuffer.flip();
        buffer.put(itemBuffer);
        delivery.sendToDatabase(address, Arrays.copyOf(buffer.array(),buffer.position());
        itemBuffer.clear();
        pendingItems = 0;
        //Properties: itemBuffer serialized size == 0
    }

    public void addAndSendJunked(final byte[] key, final byte[] data) {
        if (key.length > 255) {
            return;
        }
        if (data.length > 255) {
            return;
        }
        final byte keyLength = (byte) key.length;
        final byte dataLength = (byte) data.length;

        final int additionalSize = dataLength + keyLength + 1 + 1 + 8 + 2;
        final int newSize = itemBuffer.position() + additionalSize;
        //Properties: itemBuffer serialized size < MAX
        if (newSize >= (MAX_SIZE-HEADER_SIZE)) {
            sendData();
        }
        if (additionalSize > (MAX_SIZE-HEADER_SIZE)) {
            //XXX Use exception that is appropriate for your application
            //XXX You might add sizes involved for ease of analysis
            throw new AppConfigurationException("Size of single item exceeds maximum size");
        }
        //Properties: itemBuffer size (old+new or new) < MAX

        final ByteBuffer dataBuffer = ByteBuffer.wrap(data);
        final long timestamp = dataLength > 10 ? dataBuffer.getLong(2) : System.currentTimeMillis();
        // data layout
        itemBuffer.put((byte) 0).put(keyLength).put(key).putLong(timestamp).putShort(dataLength).put(data);
        pendingItems++ ;
</code>```

//Properties: itemBuffer size < MAX
        }

```<code>    @Override
    public void close() {
        if (pendingItems > 0) {
            sendData();
        }
    }
</code>```

Finally your calling code will mutate to:

```<code>private void validateAndSend(final Partition partition) {
    final ConcurrentLinkedQueue<DataHolder> dataHolders = dataHoldersByPartition.get(partition);

    // the instance providing sendToDatabase() method
    // just for cutting off details external to the discussion
    final DatabaseDelivery delivery = this;
    final Message message = new Message(partition, this);

    DataHolder dataHolder;
    while ((dataHolder = dataHolders.poll()) != null) {
        // XXX: why is client key using explicit encoding while process bytes is not?
        message.addAndSendJunked(dataHolder.getClientKey().getBytes(StandardCharsets.UTF_8), dataHolder.getProcessBytes());
    }
    message.close();
}
</code>```

Please note that I added some markers (XXX) at places that might need attention. (Those, however, could be explained from information external to what has been provided)

There are some more details that could be considered.
E.g. I'm not convinced that using ByteBuffer is a proper collection for the given use case (at most places).

Edit:
With respect to testing, due to the small size of the code, you might consider applying formal verification (at least partially). This is similar to what modern compilers due with static code analysis: You walk through your code (with paper and pencil) and derive properties that hold at that very place. I added comments to the code above (marked //Properties) for illustrating what you might get doing so. (Mind: this is a simple illustration, and definitely would need more properties to be derived and done for each statement). I just did some minimal attributions for resulting buffer size. (using MAX' as placeholder for the maximum acceptable size of the item part of the final buffer, akaMAX_SIZE-HEADER_SIZE`).

Of course, may people will (correctly) suggest writing tests for the critical cases. That would be whitebox tests in that case. testing for proper functionality of the code at the corner cases of the (known) implementation. You would, also need to have blackbox tests testing behavior of your code with respect to a specification.

And also you might add runtime checks for ensuring proper behavior at critical parts. E.g. when doing sendToDatabase() you could check for maximum size requirement. However, such testing would need suitable input to plausibalize proper behavior. Using properties derived from code by static analysis, could provide proof of well-behavior without the final doubt of not having found the one test case that would have caused a failure.

Body:
I have a method which takes a parameter which is Partition enum. This method will be called by multiple background threads (15 max) around same time period by passing different value of partition. Here dataHoldersByPartition is a ImmutableMap of Partition and ConcurrentLinkedQueue<DataHolder>.

  private final ImmutableMap<Partition, ConcurrentLinkedQueue<DataHolder>> dataHoldersByPartition;

  //... some code to populate entry in `dataHoldersByPartition` map

  private void validateAndSend(final Partition partition) {
    ConcurrentLinkedQueue<DataHolder> dataHolders = dataHoldersByPartition.get(partition);
    Map<byte[], byte[]> clientKeyBytesAndProcessBytesHolder = new HashMap<>();
    int totalSize = 0;
    DataHolder dataHolder;
    while ((dataHolder = dataHolders.poll())  != null) {
      byte[] clientKeyBytes = dataHolder.getClientKey().getBytes(StandardCharsets.UTF_8);
      if (clientKeyBytes.length > 255)
        continue;

      byte[] processBytes = dataHolder.getProcessBytes();
      int clientKeyLength = clientKeyBytes.length;
      int processBytesLength = processBytes.length;

      int additionalLength = clientKeyLength + processBytesLength;
      if (totalSize + additionalLength > 50000) {
        Message message = new Message(clientKeyBytesAndProcessBytesHolder, partition);
        // here size of `message.serialize()` byte array should always be less than 50k at all cost
        sendToDatabase(message.getAddress(), message.serialize());
        clientKeyBytesAndProcessBytesHolder = new HashMap<>();
        totalSize = 0;
      }
      clientKeyBytesAndProcessBytesHolder.put(clientKeyBytes, processBytes);
      totalSize += additionalLength;
    }
    // calling again with remaining values only if clientKeyBytesAndProcessBytesHolder is not empty
    if(!clientKeyBytesAndProcessBytesHolder.isEmpty()) {
        Message message = new Message(partition, clientKeyBytesAndProcessBytesHolder);
        // here size of `message.serialize()` byte array should always be less than 50k at all cost
        sendToDatabase(message.getAddress(), message.serialize());
    }
  }

And below is my Message class:

public final class Message {
  private final byte dataCenter;
  private final byte recordVersion;
  private final Map<byte[], byte[]> clientKeyBytesAndProcessBytesHolder;
  private final long address;
  private final long addressFrom;
  private final long addressOrigin;
  private final byte recordsPartition;
  private final byte replicated;

  public Message(Map<byte[], byte[]> clientKeyBytesAndProcessBytesHolder, Partition recordPartition) {
    this.clientKeyBytesAndProcessBytesHolder = clientKeyBytesAndProcessBytesHolder;
    this.recordsPartition = (byte) recordPartition.getPartition();
    this.dataCenter = Utils.CURRENT_LOCATION.get().datacenter();
    this.recordVersion = 1;
    this.replicated = 0;
    long packedAddress = new Data().packAddress();
    this.address = packedAddress;
    this.addressFrom = 0L;
    this.addressOrigin = packedAddress;
  }

  // Output of this method should always be less than 50k always
  public byte[] serialize() {
    // 36 + dataSize + 1 + 1 + keyLength + 8 + 2;
    int bufferCapacity = getBufferCapacity(clientKeyBytesAndProcessBytesHolder);

    ByteBuffer byteBuffer = ByteBuffer.allocate(bufferCapacity).order(ByteOrder.BIG_ENDIAN);
    // header layout
    byteBuffer.put(dataCenter).put(recordVersion).putInt(clientKeyBytesAndProcessBytesHolder.size())
        .putInt(bufferCapacity).putLong(address).putLong(addressFrom).putLong(addressOrigin)
        .put(recordsPartition).put(replicated);

    // data layout
    for (Map.Entry<byte[], byte[]> entry : clientKeyBytesAndProcessBytesHolder.entrySet()) {
      byte keyType = 0;
      byte[] key = entry.getKey();
      byte[] value = entry.getValue();
      byte keyLength = (byte) key.length;
      short valueLength = (short) value.length;

      ByteBuffer dataBuffer = ByteBuffer.wrap(value);
      long timestamp = valueLength > 10 ? dataBuffer.getLong(2) : System.currentTimeMillis();

      byteBuffer.put(keyType).put(keyLength).put(key).putLong(timestamp).putShort(valueLength)
          .put(value);
    }
    return byteBuffer.array();
  }

  private int getBufferCapacity(Map<byte[], byte[]> clientKeyBytesAndProcessBytesHolder) {
    int size = 36;
    for (Entry<byte[], byte[]> entry : clientKeyBytesAndProcessBytesHolder.entrySet()) {
      size += 1 + 1 + 8 + 2;
      size += entry.getKey().length;
      size += entry.getValue().length;
    }
    return size;
  }

    // getters and to string method here
}

Basically, what I have to make sure is whenever the sendToDatabase method is called in validateAndSend method, size of message.serialize() byte array should always be less than 50k at all cost. My sendToDatabase method sends byte array coming out from serialize method. So for example if I have 60k records in dataHolders CLQ then I will send in two chunks in validateAndSend method:

First, I will make a byte array  which is approx less than 50k (meaning byte array coming out from message.serialize() is less than 50k) and call sendToDatabase method on it.

Second, I will call sendToDatabase method for remianing part.

And to accomplish above things, I was having totalSize variable in validateAndSend method which is trying to measure 50k size but looks like my approach might not be right and I maybe dropping some records or sending more than 50k everytime I guess?

Looks like my Message class knows about clientKeyBytesAndProcessBytesHolder map and I can use this map to accurately define the size by calling getBufferCapacity method and if is approx less than 50k then call sendToDatabase method?

Body:
You might get cleaner code by sorting responsibilities.
Currently, Message class is responsible for converting DataHolder items into a serialized form. But also t is expected to ensure size restriction is fulfilled. Unfortunately, the calling method is checking the size expectations without knowing anything about the size requirements of Message class.

I suggest putting responsibility on sending out proper junks of data to the Message class and thus remove the "knowledge about the proper data junk formatting" to the Message class itself.

You might also have noticed that current implementation is accounting for a full header size per item, while a header is only added once per serialize()

Please find below a sketch of a suggested improvement. The code would need further polishing. But it is primarily intended for illustrating elementary improvements on structure and readability/maintainability.

For isolating the sendToDatabase() functionality from Message class I just added a simple interface:

// decoupling the sending logic from the formatting
// if external requirements suggest linking such functionality into the message class
// such interface would be unnecessary
public interface DatabaseDelivery {
    void sendToDatabase(long addres, byte[] messagePayload);
}

The message class is changed to dealing with junking and size restrictions. It is now Closeable indicating you should call close() finally. (So you might consider using proper constructs with current versions of java)

public final class Message implements Closeable {
    // or initialize it from some external source if this might change dynamically
    private static final int MAX_SIZE = 50000;
    // better determine this in sync with addHeader() method
    private static final int HEADER_SIZE = 36;

    private final byte dataCenter;
    private final byte recordVersion;
    private final long address;
    private final long addressFrom;
    private final long addressOrigin;
    private final byte recordsPartition;
    private final byte replicated;
    private final DatabaseDelivery delivery;
    private final ByteBuffer itemBuffer = ByteBuffer.allocate(MAX_SIZE);
    private int pendingItems = 0;

    public Message(final Partition recordPartition, final DatabaseDelivery databaseDelivery) {
        this.recordsPartition = (byte) recordPartition.getPartition();
        this.dataCenter = Utils.CURRENT_LOCATION.get().datacenter();
        this.recordVersion = 1;
        this.replicated = 0;
        final long packedAddress = new Data().packAddress();
        this.address = packedAddress;
        this.addressFrom = 0L;
        this.addressOrigin = packedAddress;
        this.delivery = databaseDelivery;
    }

    private void addHeader(final ByteBuffer buffer, final int items) {
        buffer.put(dataCenter)
              .put(recordVersion)
              .putInt(items)
              .putInt(buffer.capacity())
              .putLong(address)
              .putLong(addressFrom)
              .putLong(addressOrigin)
              .put(recordsPartition)
              .put(replicated);
    }

    private void sendData() {
        if (itemBuffer.position() == 0) {
            // no data to be sent
            //Properties: itemBuffer serialized size == 0
            return;
        }
        final ByteBuffer buffer = ByteBuffer.allocate(MAX_SIZE);
        addHeader(buffer, pendingItems);
        itembuffer.flip();
        buffer.put(itemBuffer);
        delivery.sendToDatabase(address, Arrays.copyOf(buffer.array(),buffer.position());
        itemBuffer.clear();
        pendingItems = 0;
        //Properties: itemBuffer serialized size == 0
    }

    public void addAndSendJunked(final byte[] key, final byte[] data) {
        if (key.length > 255) {
            return;
        }
        if (data.length > 255) {
            return;
        }
        final byte keyLength = (byte) key.length;
        final byte dataLength = (byte) data.length;

        final int additionalSize = dataLength + keyLength + 1 + 1 + 8 + 2;
        final int newSize = itemBuffer.position() + additionalSize;
        //Properties: itemBuffer serialized size < MAX
        if (newSize >= (MAX_SIZE-HEADER_SIZE)) {
            sendData();
        }
        if (additionalSize > (MAX_SIZE-HEADER_SIZE)) {
            //XXX Use exception that is appropriate for your application
            //XXX You might add sizes involved for ease of analysis
            throw new AppConfigurationException("Size of single item exceeds maximum size");
        }
        //Properties: itemBuffer size (old+new or new) < MAX

        final ByteBuffer dataBuffer = ByteBuffer.wrap(data);
        final long timestamp = dataLength > 10 ? dataBuffer.getLong(2) : System.currentTimeMillis();
        // data layout
        itemBuffer.put((byte) 0).put(keyLength).put(key).putLong(timestamp).putShort(dataLength).put(data);
        pendingItems++ ;

//Properties: itemBuffer size < MAX
        }

    @Override
    public void close() {
        if (pendingItems > 0) {
            sendData();
        }
    }

Finally your calling code will mutate to:

private void validateAndSend(final Partition partition) {
    final ConcurrentLinkedQueue<DataHolder> dataHolders = dataHoldersByPartition.get(partition);

    // the instance providing sendToDatabase() method
    // just for cutting off details external to the discussion
    final DatabaseDelivery delivery = this;
    final Message message = new Message(partition, this);

    DataHolder dataHolder;
    while ((dataHolder = dataHolders.poll()) != null) {
        // XXX: why is client key using explicit encoding while process bytes is not?
        message.addAndSendJunked(dataHolder.getClientKey().getBytes(StandardCharsets.UTF_8), dataHolder.getProcessBytes());
    }
    message.close();
}

Please note that I added some markers (XXX) at places that might need attention. (Those, however, could be explained from information external to what has been provided)

There are some more details that could be considered.
E.g. I'm not convinced that using ByteBuffer is a proper collection for the given use case (at most places).

Edit:
With respect to testing, due to the small size of the code, you might consider applying formal verification (at least partially). This is similar to what modern compilers due with static code analysis: You walk through your code (with paper and pencil) and derive properties that hold at that very place. I added comments to the code above (marked //Properties) for illustrating what you might get doing so. (Mind: this is a simple illustration, and definitely would need more properties to be derived and done for each statement). I just did some minimal attributions for resulting buffer size. (using MAX' as placeholder for the maximum acceptable size of the item part of the final buffer, akaMAX_SIZE-HEADER_SIZE`).

Of course, may people will (correctly) suggest writing tests for the critical cases. That would be whitebox tests in that case. testing for proper functionality of the code at the corner cases of the (known) implementation. You would, also need to have blackbox tests testing behavior of your code with respect to a specification.

And also you might add runtime checks for ensuring proper behavior at critical parts. E.g. when doing sendToDatabase() you could check for maximum size requirement. However, such testing would need suitable input to plausibalize proper behavior. Using properties derived from code by static analysis, could provide proof of well-behavior without the final doubt of not having found the one test case that would have caused a failure.


来源: stackexchange

问:
How to reference static assets within vue javascript
I'm looking for the right url to reference static assets, like images within Vue javascript.

For example, I'm creating a leaflet marker using a custom icon image, and I've tried several urls, but they all return a 404 (Not Found):

Main.vue:

```<code>var icon = L.icon({
    iconUrl: './assets/img.png',
    iconSize:     [25, 25],
    iconAnchor:   [12, 12]
});
</code>```

I've tried putting the images in the assets folder and the static folder with no luck.  Do I have to tell vue to load those images somehow?

答:
What system are you using? Webpack? Vue-loader?

I'll only brainstorming here...

Because .png is not a JavaScript file, you will need to configure Webpack to use file-loader or url-loader to handle them. The project scaffolded with vue-cli has also configured this for you.

You can take a look at webpack.conf.js in order to see if it's well configured like

```<code>...
    {
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('img/[name].[hash:7].[ext]')
        }
      },
...
</code>```

/assets is for files that are handles by webpack during bundling - for that, they have to be referenced somewhere in your javascript code.

Other assets can be put in /static, the content of this folder will be copied to /dist later as-is.

I recommend you to try to change:

iconUrl: './assets/img.png'

to

iconUrl: './dist/img.png'

You can read the official documentation here: https://vue-loader.vuejs.org/en/configurations/asset-url.html

Hope it helps to you!

ContentLicense: CC BY-SA 3.0

Body:
I'm looking for the right url to reference static assets, like images within Vue javascript.

For example, I'm creating a leaflet marker using a custom icon image, and I've tried several urls, but they all return a 404 (Not Found):

Main.vue:

var icon = L.icon({
    iconUrl: './assets/img.png',
    iconSize:     [25, 25],
    iconAnchor:   [12, 12]
});

I've tried putting the images in the assets folder and the static folder with no luck.  Do I have to tell vue to load those images somehow?

Body:
What system are you using? Webpack? Vue-loader?

I'll only brainstorming here...

Because .png is not a JavaScript file, you will need to configure Webpack to use file-loader or url-loader to handle them. The project scaffolded with vue-cli has also configured this for you.

You can take a look at webpack.conf.js in order to see if it's well configured like

...
    {
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('img/[name].[hash:7].[ext]')
        }
      },
...

/assets is for files that are handles by webpack during bundling - for that, they have to be referenced somewhere in your javascript code.

Other assets can be put in /static, the content of this folder will be copied to /dist later as-is.

I recommend you to try to change:

iconUrl: './assets/img.png'

to

iconUrl: './dist/img.png'

You can read the official documentation here: https://vue-loader.vuejs.org/en/configurations/asset-url.html

Hope it helps to you!


问:
how to get values of field form class object nested in another clas
```<code>public void Fill()
    {
        List<testowa1> lista = new List<testowa1>();
        var item = new testowa1()
        {
            ID = 1,
            Nazwa = "Pierwszy",
            Cena = new testowa2()
            {
                Cena = 32.22M
            }
        };
        lista.Add(item);
        lista.Add(item);
        lista.Add(item);
        lista.Add(item);

        dataGridView1.DataSource = lista;
    }

    public class testowa1
    {
        public int ID { get; set; }
        public string Nazwa { get; set; }
        public testowa2 Cena { get; set; }
    }
    public class testowa2
    {
        public decimal Cena { get; set; }
    }
</code>```

that is result:

So, how i can get value of testowa2.Cena into data grid ?
I don't know what to do. I was looking in google but nothing found

答:
You can add a property to testowa1 to expose the decimal property kept in testowa2. This will put that value into the DataGridview, but you'll still need to hide the extra column that shows testowa2 as a string.

I believe this works because Data Binding can only go one level deep in an object's properties. In your code, instead of displaying the testowa2's decimal value it would just show the string equivalent of testowa2 because it doesn't drill down into testowa2 to get the decimal value. Disclaimer: I don't actually understand data binding well and I couldn't find anything to back up my explanation. So this could be wrong, but my changes to your code do work.

```<code>public class testowa1
{
    public decimal CenaValue
    {
        get { return Cena.Cena; }
        set { Cena.Cena = value; }
    }
}

// in Fill
var item = new testowa1()
{
    ID = 1,
    Nazwa = "Pierwszy",
    Cena = new testowa2(),
    CenaValue = 32.22M
};

// after you added the list as the datasource
dataGridView1.Columns["Cena"].Visible = false;
</code>```

Body:
public void Fill()
    {
        List<testowa1> lista = new List<testowa1>();
        var item = new testowa1()
        {
            ID = 1,
            Nazwa = "Pierwszy",
            Cena = new testowa2()
            {
                Cena = 32.22M
            }
        };
        lista.Add(item);
        lista.Add(item);
        lista.Add(item);
        lista.Add(item);

        dataGridView1.DataSource = lista;
    }

    public class testowa1
    {
        public int ID { get; set; }
        public string Nazwa { get; set; }
        public testowa2 Cena { get; set; }
    }
    public class testowa2
    {
        public decimal Cena { get; set; }
    }

that is result:

So, how i can get value of testowa2.Cena into data grid ?
I don't know what to do. I was looking in google but nothing found

Body:
You can add a property to testowa1 to expose the decimal property kept in testowa2. This will put that value into the DataGridview, but you'll still need to hide the extra column that shows testowa2 as a string.

I believe this works because Data Binding can only go one level deep in an object's properties. In your code, instead of displaying the testowa2's decimal value it would just show the string equivalent of testowa2 because it doesn't drill down into testowa2 to get the decimal value. Disclaimer: I don't actually understand data binding well and I couldn't find anything to back up my explanation. So this could be wrong, but my changes to your code do work.

public class testowa1
{
    public decimal CenaValue
    {
        get { return Cena.Cena; }
        set { Cena.Cena = value; }
    }
}

// in Fill
var item = new testowa1()
{
    ID = 1,
    Nazwa = "Pierwszy",
    Cena = new testowa2(),
    CenaValue = 32.22M
};

// after you added the list as the datasource
dataGridView1.Columns["Cena"].Visible = false;


问:
How to logout from a website running in an Android Webview?
This is my code for handling login:

```<code>wblogin.getSettings().setJavaScriptEnabled(true);

wblogin.loadUrl("http://mywebsite.com/login.php");

wblogin.setWebViewClient(new WebViewClient() {
    @Override
    public void onPageFinished(WebView view, String url) {
        wblogin.loadUrl("javascript: {" +
            "document.getElementById('email').value = '" + user_name + "';" +
            "document.getElementById('password').value = '" + pass_name + "';" +
            "document.getElementById('xyz').click();" +
        "};");
    }
});
</code>```

When I logout from the website running in Webview it starts to login automatically

答:
Have you turned on a setting like "Remember my login" for the login page? Maybe it is a default checkbox set?

Second idea: Maybe the auto login after logout happens because of cookies set. Find information how to disable cookies in a webview here and here

Body:
This is my code for handling login:

wblogin.getSettings().setJavaScriptEnabled(true);

wblogin.loadUrl("http://mywebsite.com/login.php");

wblogin.setWebViewClient(new WebViewClient() {
    @Override
    public void onPageFinished(WebView view, String url) {
        wblogin.loadUrl("javascript: {" +
            "document.getElementById('email').value = '" + user_name + "';" +
            "document.getElementById('password').value = '" + pass_name + "';" +
            "document.getElementById('xyz').click();" +
        "};");
    }
});

When I logout from the website running in Webview it starts to login automatically


问:
subtract keys from dictionary if values match and return difference in python
I want to subtract the keys of two dicts if their values match. One dict looks like this

```<code>dict_one
{(2, 2): 38,
 (2, 6): 51,
 (4, 9): 29,
 (5, 1): 53,
 (6, 6): 91,
 (6, 9): 105,
 (7, 6): 66,
 (8, 4): 74,
 (8, 8): 89,
 (9, 6): 115}
</code>```

The other like this

```<code>dict_two
{(2, 1): 38,
 (2, 6): 51,
 (4, 9): 29,
 (5, 1): 53,
 (6, 6): 91,
 (6, 9): 105,
 (7, 6): 66,
 (8, 4): 74,
 (8, 8): 89,
 (9, 6): 115
</code>```

In the example here the result should be

```<code>result
(1, 0, 0, 0, 0, 0, 0, 0, 0, 0)
</code>```

Basically the value 38 in this example changed keys from (2,2) to (2,1). so the difference between these pairs of values is 1, whereas every other key stayed the same between the two dicts so the output values for the other keys are all 0.

答:
If you are looking for changed keys, then it appears you have your key-value mapping order the wrong way around. Invert one of the dictionaries, so you can easily look up the corresponding tuple for a given value.

Then loop over the sorted key-value pairs of the other:

```<code>inverted_dict_one = {v: k for k, v in dict_one.items()}
result = [abs(k[1] - inverted_dict_one[v][1] for k, v in sorted(dict_two.items())]
</code>```

Demo:

```<code>>>> inverted_dict_one = {v: k for k, v in dict_one.items()}
>>> [abs(k[1] - inverted_dict_one[v][1]) for k, v in sorted(dict_two.items())]
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
</code>```

Body:
I want to subtract the keys of two dicts if their values match. One dict looks like this

dict_one
{(2, 2): 38,
 (2, 6): 51,
 (4, 9): 29,
 (5, 1): 53,
 (6, 6): 91,
 (6, 9): 105,
 (7, 6): 66,
 (8, 4): 74,
 (8, 8): 89,
 (9, 6): 115}

The other like this

dict_two
{(2, 1): 38,
 (2, 6): 51,
 (4, 9): 29,
 (5, 1): 53,
 (6, 6): 91,
 (6, 9): 105,
 (7, 6): 66,
 (8, 4): 74,
 (8, 8): 89,
 (9, 6): 115

In the example here the result should be

result
(1, 0, 0, 0, 0, 0, 0, 0, 0, 0)

Basically the value 38 in this example changed keys from (2,2) to (2,1). so the difference between these pairs of values is 1, whereas every other key stayed the same between the two dicts so the output values for the other keys are all 0.

Body:
If you are looking for changed keys, then it appears you have your key-value mapping order the wrong way around. Invert one of the dictionaries, so you can easily look up the corresponding tuple for a given value.

Then loop over the sorted key-value pairs of the other:

inverted_dict_one = {v: k for k, v in dict_one.items()}
result = [abs(k[1] - inverted_dict_one[v][1] for k, v in sorted(dict_two.items())]

Demo:

>>> inverted_dict_one = {v: k for k, v in dict_one.items()}
>>> [abs(k[1] - inverted_dict_one[v][1]) for k, v in sorted(dict_two.items())]
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0]


问:
Aggregate data on daily intervals in R
My dataset is composed of several observations, over 3 columns (time, price and volume), as follows,

```<code>time                price   volume
2017-11-15 9:35:11  301.1   1.1
2017-11-15 9:35:09  300.9   3.0
2017-11-15 9:35:07  300.8   1.4
2017-11-15 9:35:06  300.9   0.1
2017-11-15 9:35:01  301.0   0.6
</code>```

I want to start by cut the data by periods of 24h, adding the volume for each period of 24h and obtaining the at the time the data is aggregated.

I have tried by doing the following (the initial dataset is called "mydf" on the code),

```<code>##sum the volume over periods of 24h
mydf_volume_24h <- data.frame (volume = tapply (cbind (mydf$volume), list (cut (mydf$time, breaks="24 hours")), sum))

##bind the previous df with the prices for each time label
mydf_24h <- setNames (cbind (rownames (mydf_volume_24h), mydf_volume_24h, row.names = NULL), c("time", "volume"))

mydf <- mydf %>%
select(-volume)

mydf_24h <- merge (mydf, mydf_volume_24h, by = "time")
</code>```

The problem with this code, besides (probably) being not the best/efficient way, does not result since the first part of the code gives me the the sum of the volume for a period of 24h but labeling each sum with the time 23:00:00, which not always exists on my dataset.

What I entended is to cut over 24h periods but giving me the (real) time of an observation which is the closest to the period of 24h. Is there any way to do this?

答:
This may not be exactly what you want, but from your description I gathered that you want to sum the volume for each unique day, along with getting the max time for each unique day.  If that is indeed what you want the below should work to get your aggregate data frame:</p>

```<code>library(dplyr)
library(stringr)
library(lubridate)

df <- tibble(time = c(
             "2017-11-15 9:35:11",
             "2017-11-15 9:35:09",
             "2017-11-15 9:35:07",
             "2017-11-15 9:35:06",
             "2017-11-15 9:35:01",
             "2017-11-16 9:36:12",
             "2017-11-16 9:35:09",
             "2017-11-16 9:35:07",
             "2017-11-16 9:35:06",
             "2017-11-16 9:35:01"
             ),
             price = c(301.1, 300.9, 300.8, 300.9, 301.0,
                       302, 303, 304, 305, 306),
             volume = c(1.1, 3.0, 1.4, 0.1, 0.6,
                        1.4, 3.4, 1.5, 0.5, 0.6)
)

df %>% mutate(time = ymd_hms(time)) %>%
        mutate(day = str_extract(time, "^\\S+"))  %>%
        group_by(day) %>%
        summarize(volume = sum(volume), maxTime = max(time))
</code>```

Title: Aggregate data on daily intervals in R

Body:
My dataset is composed of several observations, over 3 columns (time, price and volume), as follows,

time                price   volume
2017-11-15 9:35:11  301.1   1.1
2017-11-15 9:35:09  300.9   3.0
2017-11-15 9:35:07  300.8   1.4
2017-11-15 9:35:06  300.9   0.1
2017-11-15 9:35:01  301.0   0.6

I want to start by cut the data by periods of 24h, adding the volume for each period of 24h and obtaining the at the time the data is aggregated.

I have tried by doing the following (the initial dataset is called "mydf" on the code),

##sum the volume over periods of 24h
mydf_volume_24h <- data.frame (volume = tapply (cbind (mydf$volume), list (cut (mydf$time, breaks="24 hours")), sum))

##bind the previous df with the prices for each time label
mydf_24h <- setNames (cbind (rownames (mydf_volume_24h), mydf_volume_24h, row.names = NULL), c("time", "volume"))

mydf <- mydf %>%
select(-volume)

mydf_24h <- merge (mydf, mydf_volume_24h, by = "time")

The problem with this code, besides (probably) being not the best/efficient way, does not result since the first part of the code gives me the the sum of the volume for a period of 24h but labeling each sum with the time 23:00:00, which not always exists on my dataset.

What I entended is to cut over 24h periods but giving me the (real) time of an observation which is the closest to the period of 24h. Is there any way to do this?

Body:
This may not be exactly what you want, but from your description I gathered that you want to sum the volume for each unique day, along with getting the max time for each unique day.  If that is indeed what you want the below should work to get your aggregate data frame:

library(dplyr)
library(stringr)
library(lubridate)

df <- tibble(time = c(
             "2017-11-15 9:35:11",
             "2017-11-15 9:35:09",
             "2017-11-15 9:35:07",
             "2017-11-15 9:35:06",
             "2017-11-15 9:35:01",
             "2017-11-16 9:36:12",
             "2017-11-16 9:35:09",
             "2017-11-16 9:35:07",
             "2017-11-16 9:35:06",
             "2017-11-16 9:35:01"
             ),
             price = c(301.1, 300.9, 300.8, 300.9, 301.0,
                       302, 303, 304, 305, 306),
             volume = c(1.1, 3.0, 1.4, 0.1, 0.6,
                        1.4, 3.4, 1.5, 0.5, 0.6)
)

df %>% mutate(time = ymd_hms(time)) %>%
        mutate(day = str_extract(time, "^\\S+"))  %>%
        group_by(day) %>%
        summarize(volume = sum(volume), maxTime = max(time))


问:
SAS - Built a new table by calling a macro with a variable of another table passed as parameter
I have written this code to do this :

read records in the table "not_identified" one by one

for one record pass the "name_firstname" variable to a macro named "mCalcul_lev_D33",

then, the macro calculates the Levenstein between the variable passed as parameter and all the values of the variable "name_firstname_in_D33" in "data_all" table,

if the Levenstein returns a value less or equal to "3", then the record of "data_all" is copied to "lev_D33" table.

```<code>rsubmit;
%macro mCalcul_lev_D33(theName);
  data result.lev_D33;
   set result.data_all;
   name_LEV=complev(&theName, name_firstname_in_D33);
   if name_LEV<=3 then output;
  run;
%mend mCalcul_lev_D33;
endrsubmit;

rsubmit;
data _null_;
  set result.not_identified;
  call execute ('%mCalcul_lev_D33('||name_firstname||')');
;
run;
endrsubmit;
</code>```

There is 53700000 records in "data_all". The code is running since yesterday. Because I cannot see the result, I am asking :

Is the code doing what I want?

How coding if I want to write "name_firstname" (the variable passed like parameter) in the beginning of each record of "lev_D33"?

Thank you!

答:
D.O.:

I posit your macros are making the task more difficult than need be.  There appears to be an coding problem in that each row in not_identified record will cause the result.lev_D33 to be rebuilt.  If your long running program ever does finish, the lev_D33 output data set will correspond to only the last not_identified.

You are doing full outer join comparing ALL_COUNT * NOT_IDENT_COUNT rows in the process.

How many rows are in not_identified ?
Hopefully far less than data_all.

Is the result libname pointing to a network drive or remote server ?
Networking i/o can make things run a very long time and even win you a phone call from the network team.

A full outer join in DATA Step can be done with nested loops and a point= on the inner loop SET.  In DATA Step the outer loop is the implicit loop.

Consider this sample code:

```<code>data all_data;
  do row = 1 to 100;
    length name_firstname $20;
    name_firstname
      =  repeat (byte(65 + mod(row,26)), 4*ranuni(123))
      || repeat(byte(65 + 26*ranuni(123)), 4*ranuni(123))
    ;
    output;
  end;
run;

data not_identified;
  do row = 1 to 10;
    length name_firstname $20;
    name_firstname = repeat (byte(65 + mod(row,26)), 10*ranuni(123));
    output;
  end;
run;

data lev33;
  set all_data;
  do check_row = 1 to check_count;
    set not_identified (keep=name_firstname rename=name_firstname=check_name)
        nobs=check_count
        point=check_row
    ;
    name_lev = complev (check_name, name_firstname);
    if name_lev <= 3 then output;
  end;
run;
</code>```

This approach tests each not_identified before moving to the next row.  This is a useful method when the all_data is very large and you might want to process chunks of it at a time.  Chunk processing is an appropriate place to start macro coding:

```<code>%macro do_chunk (FROM_OBS=, TO_OBS=);
  data lev33_&FROM_OBS._&TO_OBS;
    set all_data (firstobs=&FROM_OBS obs=&TO_OBS);
    do check_row = 1 to check_count;
      set not_identified (keep=name_firstname rename=name_firstname=check_name)
          nobs=check_count
          point=check_row
      ;
      name_lev = complev (check_name, name_firstname);
      if name_lev <= 3 then output;
    end;
  run;
%mend;

%macro do_chunks;
  %local index;
  %do index = 1 %to 100 %by 10;
    %do_chunk ( FROM_OBS=&index, TO_OBS=%eval(&index+9) )
  %end;
%mend;

%do_chunks
</code>```

You might shepherd the whole the process, bypassing do_chunks and manually invoking do_chunk for various ranges of your choosing.

Body:
I have written this code to do this :

read records in the table "not_identified" one by one

for one record pass the "name_firstname" variable to a macro named "mCalcul_lev_D33",

then, the macro calculates the Levenstein between the variable passed as parameter and all the values of the variable "name_firstname_in_D33" in "data_all" table,

if the Levenstein returns a value less or equal to "3", then the record of "data_all" is copied to "lev_D33" table.

rsubmit;
%macro mCalcul_lev_D33(theName);
  data result.lev_D33;
   set result.data_all;
   name_LEV=complev(&theName, name_firstname_in_D33);
   if name_LEV<=3 then output;
  run;
%mend mCalcul_lev_D33;
endrsubmit;

rsubmit;
data _null_;
  set result.not_identified;
  call execute ('%mCalcul_lev_D33('||name_firstname||')');
;
run;
endrsubmit;

There is 53700000 records in "data_all". The code is running since yesterday. Because I cannot see the result, I am asking :

Is the code doing what I want?

How coding if I want to write "name_firstname" (the variable passed like parameter) in the beginning of each record of "lev_D33"?

Thank you!

Body:
D.O.:

I posit your macros are making the task more difficult than need be.  There appears to be an coding problem in that each row in not_identified record will cause the result.lev_D33 to be rebuilt.  If your long running program ever does finish, the lev_D33 output data set will correspond to only the last not_identified.

You are doing full outer join comparing ALL_COUNT * NOT_IDENT_COUNT rows in the process.

How many rows are in not_identified ?
Hopefully far less than data_all.

Is the result libname pointing to a network drive or remote server ?
Networking i/o can make things run a very long time and even win you a phone call from the network team.

A full outer join in DATA Step can be done with nested loops and a point= on the inner loop SET.  In DATA Step the outer loop is the implicit loop.

Consider this sample code:

data all_data;
  do row = 1 to 100;
    length name_firstname $20;
    name_firstname
      =  repeat (byte(65 + mod(row,26)), 4*ranuni(123))
      || repeat(byte(65 + 26*ranuni(123)), 4*ranuni(123))
    ;
    output;
  end;
run;

data not_identified;
  do row = 1 to 10;
    length name_firstname $20;
    name_firstname = repeat (byte(65 + mod(row,26)), 10*ranuni(123));
    output;
  end;
run;

data lev33;
  set all_data;
  do check_row = 1 to check_count;
    set not_identified (keep=name_firstname rename=name_firstname=check_name)
        nobs=check_count
        point=check_row
    ;
    name_lev = complev (check_name, name_firstname);
    if name_lev <= 3 then output;
  end;
run;

This approach tests each not_identified before moving to the next row.  This is a useful method when the all_data is very large and you might want to process chunks of it at a time.  Chunk processing is an appropriate place to start macro coding:

%macro do_chunk (FROM_OBS=, TO_OBS=);
  data lev33_&FROM_OBS._&TO_OBS;
    set all_data (firstobs=&FROM_OBS obs=&TO_OBS);
    do check_row = 1 to check_count;
      set not_identified (keep=name_firstname rename=name_firstname=check_name)
          nobs=check_count
          point=check_row
      ;
      name_lev = complev (check_name, name_firstname);
      if name_lev <= 3 then output;
    end;
  run;
%mend;

%macro do_chunks;
  %local index;
  %do index = 1 %to 100 %by 10;
    %do_chunk ( FROM_OBS=&index, TO_OBS=%eval(&index+9) )
  %end;
%mend;

%do_chunks

You might shepherd the whole the process, bypassing do_chunks and manually invoking do_chunk for various ranges of your choosing.


问:
mailto: links not opening mail app on Android in cordova app
This is driving me crazy. I'm working on a Ionic app (Cordova, Angular etc). I have a contact us link which contains a mailto: href

```<code>href="mailto:info@somedomain.net?subject=my%20App"
</code>```

I've read countless posts on SO that say you have to remove

```<code><access origin="*"/>
</code>```

from the config.xml in the project root and replace it with:

```<code><access origin="mailto:*" launch-external="true" />
</code>```

Which I've done. When I run ionic build it gets added to the config.xml in platforms/android/res/xml. But no matter what I do the link doesn't open the mail app on any Android simulator (even when email is configured in the simulator).

Sadly I don't have a device to test on - so is this just a emulator thing or am I missing something?

答:
Try this:</p>

```<code>window.location.href = "mailto:your@ema.il?subject=Works on iOS too";
</code>```

Body:
This is driving me crazy. I'm working on a Ionic app (Cordova, Angular etc). I have a contact us link which contains a mailto: href

href="mailto:info@somedomain.net?subject=my%20App"

I've read countless posts on SO that say you have to remove

<access origin="*"/>

from the config.xml in the project root and replace it with:

<access origin="mailto:*" launch-external="true" />

Which I've done. When I run ionic build it gets added to the config.xml in platforms/android/res/xml. But no matter what I do the link doesn't open the mail app on any Android simulator (even when email is configured in the simulator).

Sadly I don't have a device to test on - so is this just a emulator thing or am I missing something?

Body:
Try this:

window.location.href = "mailto:your@ema.il?subject=Works on iOS too";


问:
PreparedStatement IF EXISTS throws: org.postgresql.util.PSQLException: The column index is out of range: 1, number of columns: 0
Following code throws exception:

```<code>String sql = "DO $$ " +
            "BEGIN " +
            "IF EXISTS ( SELECT column_name FROM information_schema.COLUMNS WHERE table_name='myTable' AND column_name='myColumn') THEN " +
            "UPDATE myTable SET \"myColumn\"=? WHERE \"id\"=1; " +
            "END IF; " +
            "END " +
            "$$; ";

Connection c = DriverManager.getConnection(...);
PreparedStatement pstmt = c.prepareStatement(sql)
pstmt.setString(1, "bla bla"); // <--- EXCEPTION HERE
pstmt.executeUpdate();
</code>```

If I'm changing sql to this then it's fine:

```<code>String sql = "UPDATE myTable SET \"myColumn\"=? WHERE \"id\"=1;";
</code>```

What am I doing wrong? I want to update some columns only if they exists...

答:
Postgres docs says:

PREPARE name [ ( data_type [, ...] ) ] AS statement

...

statement

```<code>Any SELECT, INSERT, UPDATE, DELETE, or VALUES statement.
</code>```

https://www.postgresql.org/docs/9.6/static/sql-prepare.html

So it seems you can't prepare anonymous code block and I guess your code:

```<code>PreparedStatement pstmt = c.prepareStatement(sql)
</code>```

does not prepare anything. You can check it by making sql request:

```<code>select * from pg_prepared_statements;
</code>```

If you change your code like this:

```<code>String sql = "DO $$ whatever $$;";

Connection c = DriverManager.getConnection(...);
PreparedStatement pstmt = c.prepareStatement(sql);
((org.postgresql.PGStatement)pstmt).setPrepareThreshold(1); // <-- Add this line
// pstmt.setString(1, "bla bla"); // comment it out
pstmt.executeUpdate();
</code>```

you get the actual postgres error about wrong statement to prepare.

Body:
Following code throws exception:

String sql = "DO $$ " +
            "BEGIN " +
            "IF EXISTS ( SELECT column_name FROM information_schema.COLUMNS WHERE table_name='myTable' AND column_name='myColumn') THEN " +
            "UPDATE myTable SET \"myColumn\"=? WHERE \"id\"=1; " +
            "END IF; " +
            "END " +
            "$$; ";

Connection c = DriverManager.getConnection(...);
PreparedStatement pstmt = c.prepareStatement(sql)
pstmt.setString(1, "bla bla"); // <--- EXCEPTION HERE
pstmt.executeUpdate();

If I'm changing sql to this then it's fine:

String sql = "UPDATE myTable SET \"myColumn\"=? WHERE \"id\"=1;";

What am I doing wrong? I want to update some columns only if they exists...

Body:
Postgres docs says:

PREPARE name [ ( data_type [, ...] ) ] AS statement

...

statement

Any SELECT, INSERT, UPDATE, DELETE, or VALUES statement.

https://www.postgresql.org/docs/9.6/static/sql-prepare.html

So it seems you can't prepare anonymous code block and I guess your code:

PreparedStatement pstmt = c.prepareStatement(sql)

does not prepare anything. You can check it by making sql request:

select * from pg_prepared_statements;

If you change your code like this:

String sql = "DO $$ whatever $$;";

Connection c = DriverManager.getConnection(...);
PreparedStatement pstmt = c.prepareStatement(sql);
((org.postgresql.PGStatement)pstmt).setPrepareThreshold(1); // <-- Add this line
// pstmt.setString(1, "bla bla"); // comment it out
pstmt.executeUpdate();

you get the actual postgres error about wrong statement to prepare.


问:
Forced deletion of Pod on kubernetes
How do you hard force a pod to terminate?

We have tried every documented form of kubectl delete pod and they remain. kubectl reports that they've been deleted, but kubectl get pods tells a different story. All pods that they could've been using have been deleted as well as any pods that could be using them.

Is there any form of kubectl SERIOUSLY_DELETE this pod?

I've tried: kubectl delete pods --all  --grace-period=0 --force -n monitoring

With no favorable result.  I've also tried to delete them individually.

NAME                        READY     STATUS        RESTARTS   AGE
es-master-962148878-7vxpp   1/1       Terminating   1          12d
es-master-962148878-h1r4k   1/1       Terminating   1          12d
es-master-962148878-rkg9g   1/1       Terminating   1          12d

答:
Taken from kubectl delete --help:

```<code>kubectl delete pod foo --grace-period=0 --force
</code>```

Note that if your pods are controlled via e.g. a deployment, then a new one will be recreated every time you delete one.  So do make sure that's not the symptom you're observing!

Title: Forced deletion of Pod on kubernetes

Body:
Taken from kubectl delete --help:

kubectl delete pod foo --grace-period=0 --force

Note that if your pods are controlled via e.g. a deployment, then a new one will be recreated every time you delete one.  So do make sure that's not the symptom you're observing!


问:
CentOS 7.4.1708: ERROR: x265 not found using pkg-config
I'm trying to compile ffmpeg with Nvidia support following the guides on https://trac.ffmpeg.org/wiki/CompilationGuide/Centos and https://developer.nvidia.com/ffmpeg. I've ended up with the following command:

PATH="$HOME/bin:$PATH" PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" ./configure --enable-pthreads --disable-w32threads --prefix="$HOME/ffmpeg_build"   --pkg-config-flags="--static"   --extra-cflags="-I$HOME/ffmpeg_build/include -I/usr/local/cuda/include"   --extra-ldflags="-L$HOME/ffmpeg_build/lib -L/usr/local/cuda/lib64"   --extra-libs='-lpthread -lm'   --bindir="$HOME/bin"   --enable-gpl   --enable-libfdk_aac   --enable-libfreetype   --enable-libmp3lame   --enable-libopus   --enable-libvorbis   --enable-libvpx   --enable-libx264  --enable-libx265    --enable-nonfree --enable-cuda --enable-cuvid --enable-nvenc --enable-nonfree --enable-libnpp

I'm getting the wonderful error

ERROR: x265 not found using pkg-config

looking in ffbuild/config.log reveals the following error:

```<code>gcc -D_ISOC99_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -I/home/agilbert/ffmpeg_build/include -I/usr/local/cuda/include -std=c11 -fomit-frame-pointer -pthread -I/home/agilbert/ffmpeg_build/include -I/usr/include/freetype2 -I/home/agilbert/ffmpeg_build/include/opus -I/home/agilbert/ffmpeg_build/include/opus -I/home/agilbert/ffmpeg_build/include -I/home/agilbert/ffmpeg_build/include -I/home/agilbert/ffmpeg_build/include -I/home/agilbert/ffmpeg_build/include -I/home/agilbert/ffmpeg_build/include -I/home/agilbert/ffmpeg_build/include -I/home/agilbert/ffmpeg_build/include -I/home/agilbert/ffmpeg_build/include -L/home/agilbert/ffmpeg_build/lib -c -o /tmp/ffconf.MfrVBc4k/test.o /tmp/ffconf.MfrVBc4k/test.c
In file included from /tmp/ffconf.MfrVBc4k/test.c:1:0:
/home/agilbert/ffmpeg_build/include/x265.h:1753:40: error: expected ';', ',' or ')' before '&' token
 FILE* x265_csvlog_open(const x265_param& param);
                                        ^
/home/agilbert/ffmpeg_build/include/x265.h:1757:40: error: expected ';', ',' or ')' before '&' token
 void x265_csvlog_frame(const x265_param& param, const x265_picture& pic);
                                        ^
/home/agilbert/ffmpeg_build/include/x265.h:1762:64: error: expected ';', ',' or ')' before '&' token
 void x265_csvlog_encode(x265_encoder *encoder, const x265_stats& stats, int argc, char** argv);
                                                                ^
/home/agilbert/ffmpeg_build/include/x265.h:1766:36: error: expected ';', ',' or ')' before '&' token
 void x265_dither_image(x265_picture& pic, int picWidth, int picHeight, int16_t *errorBuf, int bitDepth);
                                    ^
/home/agilbert/ffmpeg_build/include/x265.h:1815:50: error: expected ';', ',' or ')' before '&' token
     FILE*         (*csvlog_open)(const x265_param&);
                                                  ^
/home/agilbert/ffmpeg_build/include/x265.h:1816:51: error: expected ';', ',' or ')' before '&' token
     void          (*csvlog_frame)(const x265_param&, const x265_picture&);
                                                   ^
/home/agilbert/ffmpeg_build/include/x265.h:1817:67: error: expected ';', ',' or ')' before '&' token
     void          (*csvlog_encode)(x265_encoder*, const x265_stats&, int, char**);
                                                                   ^
/home/agilbert/ffmpeg_build/include/x265.h:1818:47: error: expected ';', ',' or ')' before '&' token
     void          (*dither_image)(x265_picture&, int, int, int16_t*, int);
                                               ^
/home/agilbert/ffmpeg_build/include/x265.h:1820:1: warning: no semicolon at end of struct or union [enabled by default]
 } x265_api;
 ^
</code>```

gcc version is gcc-4.8.5-16.el7.x86_64

As per a question below: Yes - x265 is installed as per https://trac.ffmpeg.org/wiki/CompilationGuide/Centos and yes pkg-config is finding it. The compilation error makes me think that I'm missing a flag to the --pkg-config-flags optnion, but I can't find one that works.

Does anyone know what I should be passing to pkg-config to get it to enable x265?

答:
In case this helps anyone else, I figured out in the end that I didn't need to supply the option --enable-libx265 when you also specify --enable-nvenc.

I still don't know what the compilation error was, but with --enable-nvenc you can encode in H.265 with nVidia-based GPU acceleration.

Body:
I'm trying to compile ffmpeg with Nvidia support following the guides on https://trac.ffmpeg.org/wiki/CompilationGuide/Centos and https://developer.nvidia.com/ffmpeg. I've ended up with the following command:

PATH="$HOME/bin:$PATH" PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" ./configure --enable-pthreads --disable-w32threads --prefix="$HOME/ffmpeg_build"   --pkg-config-flags="--static"   --extra-cflags="-I$HOME/ffmpeg_build/include -I/usr/local/cuda/include"   --extra-ldflags="-L$HOME/ffmpeg_build/lib -L/usr/local/cuda/lib64"   --extra-libs='-lpthread -lm'   --bindir="$HOME/bin"   --enable-gpl   --enable-libfdk_aac   --enable-libfreetype   --enable-libmp3lame   --enable-libopus   --enable-libvorbis   --enable-libvpx   --enable-libx264  --enable-libx265    --enable-nonfree --enable-cuda --enable-cuvid --enable-nvenc --enable-nonfree --enable-libnpp

I'm getting the wonderful error

ERROR: x265 not found using pkg-config

looking in ffbuild/config.log reveals the following error:

gcc -D_ISOC99_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -I/home/agilbert/ffmpeg_build/include -I/usr/local/cuda/include -std=c11 -fomit-frame-pointer -pthread -I/home/agilbert/ffmpeg_build/include -I/usr/include/freetype2 -I/home/agilbert/ffmpeg_build/include/opus -I/home/agilbert/ffmpeg_build/include/opus -I/home/agilbert/ffmpeg_build/include -I/home/agilbert/ffmpeg_build/include -I/home/agilbert/ffmpeg_build/include -I/home/agilbert/ffmpeg_build/include -I/home/agilbert/ffmpeg_build/include -I/home/agilbert/ffmpeg_build/include -I/home/agilbert/ffmpeg_build/include -I/home/agilbert/ffmpeg_build/include -L/home/agilbert/ffmpeg_build/lib -c -o /tmp/ffconf.MfrVBc4k/test.o /tmp/ffconf.MfrVBc4k/test.c
In file included from /tmp/ffconf.MfrVBc4k/test.c:1:0:
/home/agilbert/ffmpeg_build/include/x265.h:1753:40: error: expected ';', ',' or ')' before '&' token
 FILE* x265_csvlog_open(const x265_param& param);
                                        ^
/home/agilbert/ffmpeg_build/include/x265.h:1757:40: error: expected ';', ',' or ')' before '&' token
 void x265_csvlog_frame(const x265_param& param, const x265_picture& pic);
                                        ^
/home/agilbert/ffmpeg_build/include/x265.h:1762:64: error: expected ';', ',' or ')' before '&' token
 void x265_csvlog_encode(x265_encoder *encoder, const x265_stats& stats, int argc, char** argv);
                                                                ^
/home/agilbert/ffmpeg_build/include/x265.h:1766:36: error: expected ';', ',' or ')' before '&' token
 void x265_dither_image(x265_picture& pic, int picWidth, int picHeight, int16_t *errorBuf, int bitDepth);
                                    ^
/home/agilbert/ffmpeg_build/include/x265.h:1815:50: error: expected ';', ',' or ')' before '&' token
     FILE*         (*csvlog_open)(const x265_param&);
                                                  ^
/home/agilbert/ffmpeg_build/include/x265.h:1816:51: error: expected ';', ',' or ')' before '&' token
     void          (*csvlog_frame)(const x265_param&, const x265_picture&);
                                                   ^
/home/agilbert/ffmpeg_build/include/x265.h:1817:67: error: expected ';', ',' or ')' before '&' token
     void          (*csvlog_encode)(x265_encoder*, const x265_stats&, int, char**);
                                                                   ^
/home/agilbert/ffmpeg_build/include/x265.h:1818:47: error: expected ';', ',' or ')' before '&' token
     void          (*dither_image)(x265_picture&, int, int, int16_t*, int);
                                               ^
/home/agilbert/ffmpeg_build/include/x265.h:1820:1: warning: no semicolon at end of struct or union [enabled by default]
 } x265_api;
 ^

gcc version is gcc-4.8.5-16.el7.x86_64

As per a question below: Yes - x265 is installed as per https://trac.ffmpeg.org/wiki/CompilationGuide/Centos and yes pkg-config is finding it. The compilation error makes me think that I'm missing a flag to the --pkg-config-flags optnion, but I can't find one that works.

Does anyone know what I should be passing to pkg-config to get it to enable x265?


问:
union find operation in different cases
this is a  paragraph from data structure book, by Narasimha Karumanchi (disjoint set ADT)

fast find implementation(quick find)

this method uses an array, where the array contains the set name for each element.

In this representation to perform union(a,b)[assuming that a, is in set i and b is in set j] we need to scan the complete array and change all i to j. this take O(n).

my question 1

if find operation takes O(1) then why scan complete array and change all i to j ,only two of them need to change , so how it is O(n)

============

(book 8.8 section)

using an array which stores the parent of each element instead of using root as its set name, solve union O(n)

my 2. question

how does it solve issue using parent?
And how both root and parent approaches gives us skew tree?

答:
Consider that you have 8 elements in 2 sets, where the set identifiers are 1 and 2 (so i = 1 and j = 2 in your description).
Assume that 4 elements are in set 1 (elements 0, 1, 3, 7) and 4 elements are in set 2 (elements 2, 4, 5, 6).

Quick find implementation would represent this array as:

```<code>[ 1, 1, 2, 1, 2, 2, 2, 1 ]
</code>```

And as the following representation (both elements 1 and 2 have self-loops):

```<code>     1           2
   / | \       / | \
  0  3  7     4  5  6
</code>```

If you perform union(1, 2) and only update the set identifier (let’s assume that we are updating the elements in set 2 to point to set 1), then you would have an array such as:

```<code>[ 1, 1, 1, 1, 2, 2, 2, 1 ]
</code>```

If you perform find(2) you get as a result the identifier 1, which is correct.
But if you perform find(4) you get as a result the identifier 2, which is incorrect because element 4 now belongs to set 1.

So you have to scan the complete array (and therefore the operation has time complexity O(n)) to update the identifiers, to have the following array as a result of the union operation:

```<code>[ 1, 1, 1, 1, 1, 1, 1, 1 ]
</code>```

And the following representation (with 1 having a self-loop)

```<code>         1
   / / | | \ \ \
  0 2  3 4  5 6  7
</code>```

As I'm sure you will see later in the book, there are more efficient implementations of the union-find data structure, which are based on union by rank and path compression.

Title: union find operation in different cases

Body:
Consider that you have 8 elements in 2 sets, where the set identifiers are 1 and 2 (so i = 1 and j = 2 in your description).
Assume that 4 elements are in set 1 (elements 0, 1, 3, 7) and 4 elements are in set 2 (elements 2, 4, 5, 6).

Quick find implementation would represent this array as:

[ 1, 1, 2, 1, 2, 2, 2, 1 ]

And as the following representation (both elements 1 and 2 have self-loops):

     1           2
   / | \       / | \
  0  3  7     4  5  6

If you perform union(1, 2) and only update the set identifier (let’s assume that we are updating the elements in set 2 to point to set 1), then you would have an array such as:

[ 1, 1, 1, 1, 2, 2, 2, 1 ]

If you perform find(2) you get as a result the identifier 1, which is correct.
But if you perform find(4) you get as a result the identifier 2, which is incorrect because element 4 now belongs to set 1.

So you have to scan the complete array (and therefore the operation has time complexity O(n)) to update the identifiers, to have the following array as a result of the union operation:

[ 1, 1, 1, 1, 1, 1, 1, 1 ]

And the following representation (with 1 having a self-loop)

         1
   / / | | \ \ \
  0 2  3 4  5 6  7

As I'm sure you will see later in the book, there are more efficient implementations of the union-find data structure, which are based on union by rank and path compression.


答:
Using lt

```<code>df[S].lt(df.a,0).any(axis=1)
Out[808]:
0    False
1     True
2     True
3     True
4     True
5     True
6     True
7    False
8     True
9     True
dtype: bool
</code>```

Title: Boolean slicing by comparing one to many columns in pandas

Body:
How can i compare a column to all other columns and obtain a boolean series to slice the dataframe by using i loc?

import numpy as np
import pandas as pd
a = np.random.normal(1,10,(10,1))
b = np.random.normal(1,5,(10,1))
c = np.random.normal(1,5,(10,1))
d = np.random.normal(1,5,(10,1))

e = np.append(a,b, axis = 1)
e = np.append(e,c, axis = 1)
e = np.append(e,d, axis = 1)

df = pd.DataFrame(data = e, columns=['a','b','c','d'])

          a         b          c          d
0   4.043832 -1.672865  -0.401864   3.073481
1   4.828796 -0.830688   3.652347  -1.780346
2  13.055145  5.730707  -2.305093  -4.566279
3   6.589498 -0.525029  -1.077942  -3.850963
4   5.273932 -1.003112   0.393002  -0.415573
5  -7.872004 -2.506250   1.725281   6.676886
6  -4.797119  6.448990   0.254142  -7.374601
7   8.610763  8.075350  13.043584  12.768633
8 -10.871154  2.152322   2.093089  11.570059
9 -22.148239  1.493870   3.649696   2.455621

df.loc[df.a > df.b]

Will give the desired result, but only for a 1:1 comparison

        a         b          c          d
0   4.043832 -1.672865  -0.401864   3.073481
1   4.828796 -0.830688   3.652347  -1.780346
2  13.055145  5.730707  -2.305093  -4.566279
3   6.589498 -0.525029  -1.077942  -3.850963
4   5.273932 -1.003112   0.393002  -0.415573
7   8.610763  8.075350  13.043584  12.768633

My Approach was like this:

S = ['b','c','d']

(df.a > df[S]).any(axis = 1)

0    False
1    False
2    False
3    False
4    False
5    False
6    False
7    False
8    False
9    False
dtype: bool

But unfortunately, the series is somehow False for all rows. How can i solve this Problem?

Body:
Using lt

df[S].lt(df.a,0).any(axis=1)
Out[808]:
0    False
1     True
2     True
3     True
4     True
5     True
6     True
7    False
8     True
9     True
dtype: bool


问:
Fixing or avoiding memory leak in default third party library
I developed an app that includes the ability to preview the subdivision results of a 3D model on the fly. I have my own catmull clark subdivision functions to permanently modify the geometry, but I use the .subdivisionLevel property of the SCNGeometry to temporarily subdivide the model as a preview. In most cases previewing does not automatically mean the user will go for the permanent option.

.subdivisionLevel uses (just as MDLMesh’s subdivision, which I tried as a workaround) Pixar’s OpenSubdiv to do the actual subdivision and smoothing. It works faster than my own but more importantly it doesn’t permanently modify the vertex data I provide through a SCNGeometry source.

The problem is, I can’t get it to stop leaking memory. I first noticed this a long time ago, figured it was something in my code. I don’t think it’s just one specific IOS version and it happens in both Swift and Objective C. Eventually I set up a small example adding just 1 line to the SceneKit game template in Xcode, setting the ship’s subdivisionLevel to 1. Instruments shows that immediately results in memory leaks:

I submitted a bug report to Apple a week ago but I’m not sure I can expect a reply or a fix anytime soon or at all. The screenshot is from a test with a very small model, but even with small models (hundreds to couple of thousand vertices) it leaks a lot and fast and will lead to the app crashing.

To reproduce, create a new project in Xcode based on the SceneKit game template and add the following lines to handletap:

```<code>  if result.node.geometry!.subdivisionLevel == 3 {
     result.node.geometry!.subdivisionLevel = 0
  } else {
     result.node.geometry!.subdivisionLevel = 3
  }
</code>```

(Remove the ! For objective c)
Tap the ship to leak megabytes, tap it some more and it quickly adds up.

OpenSubdiv is used in 3D Studio max as well as others obviously and it appears to be in Apple’s implementation.  So my question is: is there a way to fix/avoid this problem without giving up on the subdivision features of SceneKit entirely, or is a response from Apple my only chance?

答:
Going through the WWDC videos to get an idea of how committed Apple is to OpenSubdiv and thus the chance of them fixing the leaks, I found the subdivision can be performed on the GPU by Metal since the latest SceneKit update.

Here are the required two lines (Swift) if you want to use subdivision in SceneKit or Model IO:

```<code>let tess = SCNGeometryTessellator()
geometry.tessellator = tess
</code>```

(from  WWDC 2017 What's new in Scenekit, 23:45 into the video)

This will cause the subdivision to be performed on the GPU (thus faster, especially at higher levels), use less memory, and most importantly, releases the memory when setting the subdivision level lower or back to zero.

Body:
I developed an app that includes the ability to preview the subdivision results of a 3D model on the fly. I have my own catmull clark subdivision functions to permanently modify the geometry, but I use the .subdivisionLevel property of the SCNGeometry to temporarily subdivide the model as a preview. In most cases previewing does not automatically mean the user will go for the permanent option.

.subdivisionLevel uses (just as MDLMesh’s subdivision, which I tried as a workaround) Pixar’s OpenSubdiv to do the actual subdivision and smoothing. It works faster than my own but more importantly it doesn’t permanently modify the vertex data I provide through a SCNGeometry source.

The problem is, I can’t get it to stop leaking memory. I first noticed this a long time ago, figured it was something in my code. I don’t think it’s just one specific IOS version and it happens in both Swift and Objective C. Eventually I set up a small example adding just 1 line to the SceneKit game template in Xcode, setting the ship’s subdivisionLevel to 1. Instruments shows that immediately results in memory leaks:

I submitted a bug report to Apple a week ago but I’m not sure I can expect a reply or a fix anytime soon or at all. The screenshot is from a test with a very small model, but even with small models (hundreds to couple of thousand vertices) it leaks a lot and fast and will lead to the app crashing.

To reproduce, create a new project in Xcode based on the SceneKit game template and add the following lines to handletap:

  if result.node.geometry!.subdivisionLevel == 3 {
     result.node.geometry!.subdivisionLevel = 0
  } else {
     result.node.geometry!.subdivisionLevel = 3
  }

(Remove the ! For objective c)
Tap the ship to leak megabytes, tap it some more and it quickly adds up.

OpenSubdiv is used in 3D Studio max as well as others obviously and it appears to be in Apple’s implementation.  So my question is: is there a way to fix/avoid this problem without giving up on the subdivision features of SceneKit entirely, or is a response from Apple my only chance?

Body:
Going through the WWDC videos to get an idea of how committed Apple is to OpenSubdiv and thus the chance of them fixing the leaks, I found the subdivision can be performed on the GPU by Metal since the latest SceneKit update.

Here are the required two lines (Swift) if you want to use subdivision in SceneKit or Model IO:

let tess = SCNGeometryTessellator()
geometry.tessellator = tess

(from  WWDC 2017 What's new in Scenekit, 23:45 into the video)

This will cause the subdivision to be performed on the GPU (thus faster, especially at higher levels), use less memory, and most importantly, releases the memory when setting the subdivision level lower or back to zero.


问:
Get list of databases, tables, columns, and column datatypes
I would like to get a collection of all user databases, all the tables within each database, and columns and their datatypes for each of the tables. I have a SQL script that gets the database names I am looking for (and excludes those I am not, like system databases)...

```<code>DECLARE @DatabaseIgnoreList AS VARCHAR(500);
SET @DatabaseIgnoreList = 'DatabaseNotToInclude';

SELECT name, database_id
FROM sys.databases
WHERE HAS_DBACCESS(name) = 1
AND name NOT IN ('msdb')
AND database_id > 4
AND name NOT LIKE '%$%'
AND name NOT IN (@DatabaseIgnoreList)
ORDER BY name ASC
</code>```

I also have a separate SQL script that gets all the tables and columns from a specific database. I found this from this SO question/answer.

```<code>USE DatabaseName;
SELECT TABLE_SCHEMA ,
   TABLE_NAME ,
   COLUMN_NAME ,
   ORDINAL_POSITION ,
   COLUMN_DEFAULT ,
   DATA_TYPE ,
   CHARACTER_MAXIMUM_LENGTH ,
   NUMERIC_PRECISION ,
   NUMERIC_PRECISION_RADIX ,
   NUMERIC_SCALE ,
   DATETIME_PRECISION
FROM INFORMATION_SCHEMA.COLUMNS;
</code>```

What I am not sure how to do is to link the two. For each database I would like to run the table/column discover script and end up with one single table that has the database name, table name, column name, and column datatype.

Is this a situation for a cursor? I am using SQL Server 2008+.

答:
Here is another approach. This is not using any cursors or loops. It is a single result set with one extra column for the database name. There are several comments in the code to help.

FWIW - I just tested this on a dev server that has 60 databases. It returned all 165,000+ rows in just over 15 seconds.

```<code>DECLARE @DatabaseIgnoreList AS VARCHAR(500);
SET @DatabaseIgnoreList = 'DatabaseNotToInclude';

declare @SQL nvarchar(max) = ''

select @SQL = @SQL +
    'SELECT ''' + quotename(name) + ''' as DatabaseName,
       TABLE_SCHEMA  = TABLE_SCHEMA collate database_default,
       TABLE_NAME = TABLE_NAME COLLATE database_default ,
       COLUMN_NAME = COLUMN_NAME COLLATE database_default ,
       ORDINAL_POSITION ,
       COLUMN_DEFAULT = COLUMN_DEFAULT COLLATE database_default ,
       DATA_TYPE = DATA_TYPE COLLATE database_default ,
       CHARACTER_MAXIMUM_LENGTH ,
       NUMERIC_PRECISION ,
       NUMERIC_PRECISION_RADIX ,
       NUMERIC_SCALE ,
       DATETIME_PRECISION
    FROM ' + quotename(name) + '.INFORMATION_SCHEMA.COLUMNS union all '
FROM sys.databases
WHERE HAS_DBACCESS(name) = 1
    --AND name NOT IN ('msdb') --why bother? You already exclude this with database_id > 4
    AND database_id > 4
    AND name NOT LIKE '%$%'
    AND name <> @DatabaseIgnoreList --if you need to exclude more than 1 we need a little different approach here
    and state_desc = 'ONLINE' --want to exclude any offline databases
ORDER BY name ASC

set @SQL = left(@SQL, LEN(@SQL) - 10) + ' order by DatabaseName, TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME' --This will order the entire result set

select @SQL
--uncomment the line below when you are satisfied the dynamic sql is correct
--exec sp_executesql @SQL
</code>```

Body:
I would like to get a collection of all user databases, all the tables within each database, and columns and their datatypes for each of the tables. I have a SQL script that gets the database names I am looking for (and excludes those I am not, like system databases)...

DECLARE @DatabaseIgnoreList AS VARCHAR(500);
SET @DatabaseIgnoreList = 'DatabaseNotToInclude';

SELECT name, database_id
FROM sys.databases
WHERE HAS_DBACCESS(name) = 1
AND name NOT IN ('msdb')
AND database_id > 4
AND name NOT LIKE '%$%'
AND name NOT IN (@DatabaseIgnoreList)
ORDER BY name ASC

I also have a separate SQL script that gets all the tables and columns from a specific database. I found this from this SO question/answer.

USE DatabaseName;
SELECT TABLE_SCHEMA ,
   TABLE_NAME ,
   COLUMN_NAME ,
   ORDINAL_POSITION ,
   COLUMN_DEFAULT ,
   DATA_TYPE ,
   CHARACTER_MAXIMUM_LENGTH ,
   NUMERIC_PRECISION ,
   NUMERIC_PRECISION_RADIX ,
   NUMERIC_SCALE ,
   DATETIME_PRECISION
FROM INFORMATION_SCHEMA.COLUMNS;

What I am not sure how to do is to link the two. For each database I would like to run the table/column discover script and end up with one single table that has the database name, table name, column name, and column datatype.

Is this a situation for a cursor? I am using SQL Server 2008+.

Body:
Here is another approach. This is not using any cursors or loops. It is a single result set with one extra column for the database name. There are several comments in the code to help.

FWIW - I just tested this on a dev server that has 60 databases. It returned all 165,000+ rows in just over 15 seconds.

DECLARE @DatabaseIgnoreList AS VARCHAR(500);
SET @DatabaseIgnoreList = 'DatabaseNotToInclude';

declare @SQL nvarchar(max) = ''

select @SQL = @SQL +
    'SELECT ''' + quotename(name) + ''' as DatabaseName,
       TABLE_SCHEMA  = TABLE_SCHEMA collate database_default,
       TABLE_NAME = TABLE_NAME COLLATE database_default ,
       COLUMN_NAME = COLUMN_NAME COLLATE database_default ,
       ORDINAL_POSITION ,
       COLUMN_DEFAULT = COLUMN_DEFAULT COLLATE database_default ,
       DATA_TYPE = DATA_TYPE COLLATE database_default ,
       CHARACTER_MAXIMUM_LENGTH ,
       NUMERIC_PRECISION ,
       NUMERIC_PRECISION_RADIX ,
       NUMERIC_SCALE ,
       DATETIME_PRECISION
    FROM ' + quotename(name) + '.INFORMATION_SCHEMA.COLUMNS union all '
FROM sys.databases
WHERE HAS_DBACCESS(name) = 1
    --AND name NOT IN ('msdb') --why bother? You already exclude this with database_id > 4
    AND database_id > 4
    AND name NOT LIKE '%$%'
    AND name <> @DatabaseIgnoreList --if you need to exclude more than 1 we need a little different approach here
    and state_desc = 'ONLINE' --want to exclude any offline databases
ORDER BY name ASC

set @SQL = left(@SQL, LEN(@SQL) - 10) + ' order by DatabaseName, TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME' --This will order the entire result set

select @SQL
--uncomment the line below when you are satisfied the dynamic sql is correct
--exec sp_executesql @SQL


问:
Spring Boot, Spring Security - Prevent direct URL query of MongoDB
So, I'm working on a Spring Boot Web App that utilizes Spring Security for login authentication. Currently, we have three types of users who get redirected to the appropriate dashboard and when they try to access the other dashboards through a direct URL, they are denied access. Any unauthenticated user is also denied access to the rest of the site. While testing, I had found that once a user had successfully been authenticated, if they were to use a direct URL to "/", or localhost:8080 for testing, instead of being redirected to the login page as they would when not authenticated, a JSON with information of our tables in our MongoDB instance would be returned. Worse, if they appended a table name to the URL, they would receive the entire table in JSON form.

Example: http://localhost:8080/premios (Currently holding dummy values)

```<code>{
  "_embedded" : {
    "premios" : [ {
      "title" : "hdlkfjgd",
      "description" : "dflgkj",
      "points" : 20,
      "enabled" : false,
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/premios/5a013a974833be43fa38dc53"
        },
        "premio" : {
          "href" : "http://localhost:8080/premios/5a013a974833be43fa38dc53"
        }
      }
    }, {
      "title" : "dfdggd",
      "description" : "dfgd",
      "points" : 5,
      "enabled" : false,
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/premios/5a0a11964833be69a480a901"
        },
        "premio" : {
          "href" : "http://localhost:8080/premios/5a0a11964833be69a480a901"
        }
      }
    }, {
      "title" : "alksksjlkakjf",
      "description" : "sdlkfkjsdlfkj",
      "points" : 5,
      "enabled" : false,
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/premios/5a0a12b24833be6a6e47a22a"
        },
        "premio" : {
          "href" : "http://localhost:8080/premios/5a0a12b24833be6a6e47a22a"
        }
      }
    } ]
  },
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/premios{?page,size,sort}",
      "templated" : true
    },
    "profile" : {
      "href" : "http://localhost:8080/profile/premios"
    },
    "search" : {
      "href" : "http://localhost:8080/premios/search"
    }
  },
  "page" : {
    "size" : 20,
    "totalElements" : 3,
    "totalPages" : 1,
    "number" : 0
  }
}
</code>```

How can I prevent this? Is this due to how I have Spring Security set up, or something I need to do on our mLab to only allow controllers on the backend to make queries? The above premios URL is not a defined request method in any of our controllers so I'm not sure why it's working. Here's how it's configured:

WebSecurityConfig.java

```<code>@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private SimpleAuthenticationSuccessHandler successHandler;

    @Autowired
    public void configureGlobal(
            AuthenticationManagerBuilder auth,
            CustomUserDetailsService userDetailsService) throws Exception {
        auth
          .userDetailsService(userDetailsService);
    }

    @Override
    protected void configure(HttpSecurity http)
            throws Exception {
        http
          .csrf().disable()
          .authorizeRequests()
            .antMatchers("/css/**", "/js/**", "/images/**", "/script/**").permitAll()
            .antMatchers("/signup").permitAll()
            .antMatchers("/webapp/admin").hasRole("ADMIN")
            .antMatchers("/webapp/sales").hasRole("SALES")
            .antMatchers("/webapp/business").hasRole("USER")
            .anyRequest().authenticated()
            .and()
          .formLogin()
            .successHandler(successHandler)
            .loginPage("/login")
            .permitAll()
            .and()
          .logout()
            .logoutRequestMatcher(new AntPathRequestMatcher(("/logout")))
            .logoutSuccessUrl("/login")
            .permitAll();
    }
}
</code>```

SimpleAuthenticationSuccessHandler.java

```<code>@Component
public class SimpleAuthenticationSuccessHandler implements AuthenticationSuccessHandler{

    private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();

    @Override
    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest,
                                        HttpServletResponse httpServletResponse,
                                        Authentication authentication) throws IOException, ServletException {

        Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
        authorities.forEach(authority -> {
            if(authority.getAuthority().equals("ROLE_ADMIN")) {
                try {
                    redirectStrategy.sendRedirect(httpServletRequest, httpServletResponse, "/webapp/admin");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            else if(authority.getAuthority().equals("ROLE_SALES")) {
                try {
                    redirectStrategy.sendRedirect(httpServletRequest, httpServletResponse, "/webapp/sales");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            else if(authority.getAuthority().equals("ROLE_USER")) {
                try {
                    redirectStrategy.sendRedirect(httpServletRequest, httpServletResponse, "/webapp/business");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            else {
                throw new IllegalStateException();
            }
        });
    }
}
</code>```

Maybe, it's something to do with the success handler? I'm new to using Spring Boot and building a Web App so any help is much appreciated!

答:
For anyone with a similar issue, I solved my problem by changing:

```<code>.anyRequest().authenticated()
</code>```

to

```<code>.anyRequest().denyAll().
</code>```

Once a user was authenticated, they were able to make any request of our Web App. By using denyAll, we could prevent all requests that were not specified in our antmatchers. I also modified antmatchers such as this:

```<code>.antMatchers("/webapp/business").hasRole("USER")
</code>```

to

```<code>.antMatchers("/webapp/business").access("isFullyAuthenticated() and hasRole('USER')")
</code>```

And just in case, I made sure to reroute any requests to "/" to our login page "/login".

Body:
So, I'm working on a Spring Boot Web App that utilizes Spring Security for login authentication. Currently, we have three types of users who get redirected to the appropriate dashboard and when they try to access the other dashboards through a direct URL, they are denied access. Any unauthenticated user is also denied access to the rest of the site. While testing, I had found that once a user had successfully been authenticated, if they were to use a direct URL to "/", or localhost:8080 for testing, instead of being redirected to the login page as they would when not authenticated, a JSON with information of our tables in our MongoDB instance would be returned. Worse, if they appended a table name to the URL, they would receive the entire table in JSON form.

Example: http://localhost:8080/premios (Currently holding dummy values)

{
  "_embedded" : {
    "premios" : [ {
      "title" : "hdlkfjgd",
      "description" : "dflgkj",
      "points" : 20,
      "enabled" : false,
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/premios/5a013a974833be43fa38dc53"
        },
        "premio" : {
          "href" : "http://localhost:8080/premios/5a013a974833be43fa38dc53"
        }
      }
    }, {
      "title" : "dfdggd",
      "description" : "dfgd",
      "points" : 5,
      "enabled" : false,
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/premios/5a0a11964833be69a480a901"
        },
        "premio" : {
          "href" : "http://localhost:8080/premios/5a0a11964833be69a480a901"
        }
      }
    }, {
      "title" : "alksksjlkakjf",
      "description" : "sdlkfkjsdlfkj",
      "points" : 5,
      "enabled" : false,
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/premios/5a0a12b24833be6a6e47a22a"
        },
        "premio" : {
          "href" : "http://localhost:8080/premios/5a0a12b24833be6a6e47a22a"
        }
      }
    } ]
  },
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/premios{?page,size,sort}",
      "templated" : true
    },
    "profile" : {
      "href" : "http://localhost:8080/profile/premios"
    },
    "search" : {
      "href" : "http://localhost:8080/premios/search"
    }
  },
  "page" : {
    "size" : 20,
    "totalElements" : 3,
    "totalPages" : 1,
    "number" : 0
  }
}

How can I prevent this? Is this due to how I have Spring Security set up, or something I need to do on our mLab to only allow controllers on the backend to make queries? The above premios URL is not a defined request method in any of our controllers so I'm not sure why it's working. Here's how it's configured:

WebSecurityConfig.java

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private SimpleAuthenticationSuccessHandler successHandler;

    @Autowired
    public void configureGlobal(
            AuthenticationManagerBuilder auth,
            CustomUserDetailsService userDetailsService) throws Exception {
        auth
          .userDetailsService(userDetailsService);
    }

    @Override
    protected void configure(HttpSecurity http)
            throws Exception {
        http
          .csrf().disable()
          .authorizeRequests()
            .antMatchers("/css/**", "/js/**", "/images/**", "/script/**").permitAll()
            .antMatchers("/signup").permitAll()
            .antMatchers("/webapp/admin").hasRole("ADMIN")
            .antMatchers("/webapp/sales").hasRole("SALES")
            .antMatchers("/webapp/business").hasRole("USER")
            .anyRequest().authenticated()
            .and()
          .formLogin()
            .successHandler(successHandler)
            .loginPage("/login")
            .permitAll()
            .and()
          .logout()
            .logoutRequestMatcher(new AntPathRequestMatcher(("/logout")))
            .logoutSuccessUrl("/login")
            .permitAll();
    }
}

SimpleAuthenticationSuccessHandler.java

@Component
public class SimpleAuthenticationSuccessHandler implements AuthenticationSuccessHandler{

    private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();

    @Override
    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest,
                                        HttpServletResponse httpServletResponse,
                                        Authentication authentication) throws IOException, ServletException {

        Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
        authorities.forEach(authority -> {
            if(authority.getAuthority().equals("ROLE_ADMIN")) {
                try {
                    redirectStrategy.sendRedirect(httpServletRequest, httpServletResponse, "/webapp/admin");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            else if(authority.getAuthority().equals("ROLE_SALES")) {
                try {
                    redirectStrategy.sendRedirect(httpServletRequest, httpServletResponse, "/webapp/sales");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            else if(authority.getAuthority().equals("ROLE_USER")) {
                try {
                    redirectStrategy.sendRedirect(httpServletRequest, httpServletResponse, "/webapp/business");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            else {
                throw new IllegalStateException();
            }
        });
    }
}

Maybe, it's something to do with the success handler? I'm new to using Spring Boot and building a Web App so any help is much appreciated!

Body:
For anyone with a similar issue, I solved my problem by changing:

.anyRequest().authenticated()

to

.anyRequest().denyAll().

Once a user was authenticated, they were able to make any request of our Web App. By using denyAll, we could prevent all requests that were not specified in our antmatchers. I also modified antmatchers such as this:

.antMatchers("/webapp/business").hasRole("USER")

to

.antMatchers("/webapp/business").access("isFullyAuthenticated() and hasRole('USER')")

And just in case, I made sure to reroute any requests to "/" to our login page "/login".


问:
Is using output buffering considered a bad practice?
Are ob_start / ob_get_clean() considered bad practice by php programmers in general?

Are there any disadvantages of output buffering?

答: It's actually a good practice. Speed up data transfer</p>

ContentLicense: CC BY-SA 2.5