问:
Entity save() Method Hangs with No Error
I am facing an issue where my Simple AGI Application hangs when saving/updating an entity and no errors are thrown. Select query / methods from Repository work as expected without any errors. I am using Spring Boot with the Spring Data JPA which persists to a MYSQL Database.

Subscriber.java :

```<code>package com.newcom.ncivr.model;

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import javax.persistence.*;

@Entity @Table(name = "subscribers")
public class Subscriber{

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int Id;
    private String msisdn;
    private String subscriptionName;
    @Column(columnDefinition = "DATETIME")
    private DateTime lastRenewal;
    private String status;

    public Subscriber() {
    }

    public Subscriber(String msisdn, String subscriptionName) {
        this.msisdn = msisdn;
        this.subscriptionName = subscriptionName;
        this.lastRenewal = DateTime.now(DateTimeZone.UTC).minusDays(1);
        this.status = "ACTIVE";
    }

 //POJO Getters and Setters Excluded from Sample

}
</code>```

SubscriberRepository.java :

```<code>package com.newcom.ncivr.repository;

import com.newcom.ncivr.model.Subscriber;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface SubscriberRepository extends CrudRepository<Subscriber,Integer>{
    Subscriber findFirstByMsisdnAndSubscriptionNameAndStatus(String msisdn, String subscriptionName, String status);
}
</code>```

IvrAgi.java :

```<code>package com.newcom.ncivr.agi;

import com.newcom.ncivr.model.Subscriber;
import com.newcom.ncivr.repository.SubscriberRepository;
import org.asteriskjava.fastagi.*;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

public class IvrAgi extends BaseAgiScript {

    private Logger log = LoggerFactory.getLogger(IvrAgi.class);

    @Autowired
    SubscriberRepository subscriberRepository;

    public void service(AgiRequest request, AgiChannel channel) throws AgiException {

        log.info("********** Agi Script Started. **************");
        // Answer the channel...
        answer();
        log.info("Caller ID: "+request.getCallerIdNumber());
        mainMenu(request);
        log.info("********** Agi Script Completed. **************");

    }

    public void mainMenu(AgiRequest request) throws AgiException {
        try {

            while (true) {

                String data = getData("ivr_main_menu");

                log.info("User Input : " + data);

                if (data.equals("1")) {
                    System.out.println(request.getCallerIdNumber() + ": User Selected 1");
                    streamFile("ivr_opt_one");
                    log.info(request.getCallerIdNumber() + ": User Selected 1");

                    try {
                        Subscriber subscriber = subscriberRepository.findFirstByMsisdnAndSubscriptionNameAndStatus(request.getCallerIdNumber(),"NEWS", "ACTIVE");

                        if(subscriber != null){
                            log.info("Id --->" + subscriber.toString());

                                subscriber.setLastRenewal(DateTime.now(DateTimeZone.UTC));
                                subscriber = subscriberRepository.save(subscriber);

                                log.info("Updated Entity --> " + subscriber.toString());
                        }else{
                            log.info("User is NOT Subscribed to NEWS");
                        }

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

                    hangup();
                }else{
                    continue;
                }
            }

        } catch (Throwable e) {
            e.printStackTrace();
        }
    }
}
</code>```

Application Main :

```<code>package com.newcom.ncivr;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ImportResource;

@SpringBootApplication
@ImportResource("classpath:/asterisk/asterisk-config.xml")
public class IvrApplication {
    @Autowired
    public static void main(String[] args) {
        SpringApplication.run(IvrApplication.class, args);
    }
}
</code>```

asterisk-config.xml (Mapping Asterisk AGI to Spring Boot Service) :

```<code><?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">

    <bean id="agiServer" class="org.asteriskjava.fastagi.DefaultAgiServer"
          init-method="startup" destroy-method="shutdown">
        <!--<property name="port" value="1111"/>-->
        <property name="mappingStrategy" ref="mappingStrategy"/>
    </bean>

    <bean id="vanivr" class="com.newcom.ncivr.agi.IvrAgi">
    </bean>

    <bean id="mappingStrategy" class="org.asteriskjava.fastagi.SimpleMappingStrategy">
        <property name="mappings">
            <map>
                <entry key="vanivr.agi" value-ref="vanivr"/>
            </map>
        </property>
    </bean>

</beans>
</code>```

application.properties :

```<code>#Database connection settings
spring.datasource.url=jdbc:mysql://localhost:3306/ncivr?useSSL=false
spring.datasource.username=root
spring.datasource.password=
spring.jpa.database=MYSQL
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.hibernate.naming.strategy=org.hibernate.cfg.ImprovedNamingStrategy
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.jpa.properties.jadira.usertype.autoRegisterUserTypes = true
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
spring.jpa.properties.hibernate.show_sql=false
spring.jpa.properties.hibernate.use_sql_comments=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.type=trace
logging.level.org.hibernate=TRACE
debug=true
</code>```

答:
The Issue was resolved by running the AgiServer using a AgiServerThread.

Updated asterisk-conf.xml :

```<code><?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">

    <bean class="org.asteriskjava.fastagi.AgiServerThread"
          init-method="startup" destroy-method="shutdown">
        <property name="agiServer" ref="agiServer"/>
    </bean>

    <bean id="agiServer" class="org.asteriskjava.fastagi.DefaultAgiServer">
          <!--init-method="startup" destroy-method="shutdown">-->
        <property name="port" value="4573"/>
        <property name="mappingStrategy" ref="mappingStrategy"/>
    </bean>

    <bean id="vanivr" class="com.newcom.ncivr.agi.IvrAgi">
    </bean>

    <bean id="mappingStrategy" class="org.asteriskjava.fastagi.SimpleMappingStrategy">
        <property name="mappings">
            <map>
                <entry key="vanivr.agi" value-ref="vanivr"/>
            </map>
        </property>
    </bean>

</beans>
</code>```

Body:
I am facing an issue where my Simple AGI Application hangs when saving/updating an entity and no errors are thrown. Select query / methods from Repository work as expected without any errors. I am using Spring Boot with the Spring Data JPA which persists to a MYSQL Database.

Subscriber.java :

package com.newcom.ncivr.model;

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import javax.persistence.*;

@Entity @Table(name = "subscribers")
public class Subscriber{

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int Id;
    private String msisdn;
    private String subscriptionName;
    @Column(columnDefinition = "DATETIME")
    private DateTime lastRenewal;
    private String status;

    public Subscriber() {
    }

    public Subscriber(String msisdn, String subscriptionName) {
        this.msisdn = msisdn;
        this.subscriptionName = subscriptionName;
        this.lastRenewal = DateTime.now(DateTimeZone.UTC).minusDays(1);
        this.status = "ACTIVE";
    }

 //POJO Getters and Setters Excluded from Sample

}

SubscriberRepository.java :

package com.newcom.ncivr.repository;

import com.newcom.ncivr.model.Subscriber;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface SubscriberRepository extends CrudRepository<Subscriber,Integer>{
    Subscriber findFirstByMsisdnAndSubscriptionNameAndStatus(String msisdn, String subscriptionName, String status);
}

IvrAgi.java :

package com.newcom.ncivr.agi;

import com.newcom.ncivr.model.Subscriber;
import com.newcom.ncivr.repository.SubscriberRepository;
import org.asteriskjava.fastagi.*;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

public class IvrAgi extends BaseAgiScript {

    private Logger log = LoggerFactory.getLogger(IvrAgi.class);

    @Autowired
    SubscriberRepository subscriberRepository;

    public void service(AgiRequest request, AgiChannel channel) throws AgiException {

        log.info("********** Agi Script Started. **************");
        // Answer the channel...
        answer();
        log.info("Caller ID: "+request.getCallerIdNumber());
        mainMenu(request);
        log.info("********** Agi Script Completed. **************");

    }

    public void mainMenu(AgiRequest request) throws AgiException {
        try {

            while (true) {

                String data = getData("ivr_main_menu");

                log.info("User Input : " + data);

                if (data.equals("1")) {
                    System.out.println(request.getCallerIdNumber() + ": User Selected 1");
                    streamFile("ivr_opt_one");
                    log.info(request.getCallerIdNumber() + ": User Selected 1");

                    try {
                        Subscriber subscriber = subscriberRepository.findFirstByMsisdnAndSubscriptionNameAndStatus(request.getCallerIdNumber(),"NEWS", "ACTIVE");

                        if(subscriber != null){
                            log.info("Id --->" + subscriber.toString());

                                subscriber.setLastRenewal(DateTime.now(DateTimeZone.UTC));
                                subscriber = subscriberRepository.save(subscriber);

                                log.info("Updated Entity --> " + subscriber.toString());
                        }else{
                            log.info("User is NOT Subscribed to NEWS");
                        }

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

                    hangup();
                }else{
                    continue;
                }
            }

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

Application Main :

package com.newcom.ncivr;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ImportResource;

@SpringBootApplication
@ImportResource("classpath:/asterisk/asterisk-config.xml")
public class IvrApplication {
    @Autowired
    public static void main(String[] args) {
        SpringApplication.run(IvrApplication.class, args);
    }
}

asterisk-config.xml (Mapping Asterisk AGI to Spring Boot Service) :

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">

    <bean id="agiServer" class="org.asteriskjava.fastagi.DefaultAgiServer"
          init-method="startup" destroy-method="shutdown">

        <property name="mappingStrategy" ref="mappingStrategy"/>
    </bean>

    <bean id="vanivr" class="com.newcom.ncivr.agi.IvrAgi">
    </bean>

    <bean id="mappingStrategy" class="org.asteriskjava.fastagi.SimpleMappingStrategy">
        <property name="mappings">
            <map>
                <entry key="vanivr.agi" value-ref="vanivr"/>
            </map>
        </property>
    </bean>

</beans>

application.properties :

#Database connection settings
spring.datasource.url=jdbc:mysql://localhost:3306/ncivr?useSSL=false
spring.datasource.username=root
spring.datasource.password=
spring.jpa.database=MYSQL
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.hibernate.naming.strategy=org.hibernate.cfg.ImprovedNamingStrategy
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.jpa.properties.jadira.usertype.autoRegisterUserTypes = true
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
spring.jpa.properties.hibernate.show_sql=false
spring.jpa.properties.hibernate.use_sql_comments=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.type=trace
logging.level.org.hibernate=TRACE
debug=true

Body:
The Issue was resolved by running the AgiServer using a AgiServerThread.

Updated asterisk-conf.xml :

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">

    <bean class="org.asteriskjava.fastagi.AgiServerThread"
          init-method="startup" destroy-method="shutdown">
        <property name="agiServer" ref="agiServer"/>
    </bean>

    <bean id="agiServer" class="org.asteriskjava.fastagi.DefaultAgiServer">
          <!--init-method="startup" destroy-method="shutdown">-->
        <property name="port" value="4573"/>
        <property name="mappingStrategy" ref="mappingStrategy"/>
    </bean>

    <bean id="vanivr" class="com.newcom.ncivr.agi.IvrAgi">
    </bean>

    <bean id="mappingStrategy" class="org.asteriskjava.fastagi.SimpleMappingStrategy">
        <property name="mappings">
            <map>
                <entry key="vanivr.agi" value-ref="vanivr"/>
            </map>
        </property>
    </bean>

</beans>


来源: stackexchange

问:
Rails 3 loading all models on startup
I have a class method mixed in to all my models. the method gets called when the model class is evaluated. unfortunately (for me), this seems to be on-demand, whenever the model is needed in development env. how can have rails load all the models at start up? is this even advisable?

```<code>class Foo < ActiveRecord::Base
  include Acl
  register_acl # i need this to be called for all models at start up
end
</code>```

Basically, the register_acl takes a few arguments of "actions" that the model would like to be access controlled. Suppose one of the action of Foo is "manage" and the system needs to be aware of this action at start up. I think in the model is the most natural place to have this logic.

thank you!

答:
I dont know if this is ideal, but it works for me. Somewhere in the config/initialize/, i do this:

```<code>Dir.glob("#{Rails.root}/app/models/*.rb").sort.each { |file| require_dependency file }
</code>```

and that preloads my models

ContentLicense: CC BY-SA 2.5

Title: Rails 3 loading all models on startup

Body:
I have a class method mixed in to all my models. the method gets called when the model class is evaluated. unfortunately (for me), this seems to be on-demand, whenever the model is needed in development env. how can have rails load all the models at start up? is this even advisable?

class Foo < ActiveRecord::Base
  include Acl
  register_acl # i need this to be called for all models at start up
end

Basically, the register_acl takes a few arguments of "actions" that the model would like to be access controlled. Suppose one of the action of Foo is "manage" and the system needs to be aware of this action at start up. I think in the model is the most natural place to have this logic.

thank you!

Body:
I dont know if this is ideal, but it works for me. Somewhere in the config/initialize/, i do this:

Dir.glob("#{Rails.root}/app/models/*.rb").sort.each { |file| require_dependency file }

and that preloads my models


问:
Why training loss is increased at the beginning of each epoch?
I'm training a linear regression model. I use tf.contrib.data to prepare the dataset, shuffle it and serve it in batches:

```<code>  dataset = tf.contrib.data.TFRecordDataset(filename)
  dataset = dataset.map(
      _parse_function, num_threads=16, output_buffer_size=100 * batch_size)
  dataset = dataset.repeat(5)
  dataset = dataset.shuffle(buffer_size=100000)
  dataset = dataset.padded_batch(batch_size, padded_shapes=([None], [None]))
  iterator = dataset.make_initializable_iterator()
  x_inputs, y_ = iterator.get_next()
</code>```

The following is our training loss:

It is very strange that at the beginning of each epoch (iteration=100k) we have a pulse in the training loss. If the training process continues, we see the same pattern at the beginning of the following epochs.

答:
Assuming that your dataset has fewer than 100000 records, the problem could be insufficient randomness in the input shuffle. Intuitively, if the existing data are not shuffled and have some structure in their order, the training process could overfit to the records towards the end of the file, and when you restart at the beginning, the model will not perform as well on the records near the beginning of the file, and the loss will increase.

The proper solution will depend on the precise details of your dataset, but some of the following approaches might be useful:

If possible, increase the buffer_size you pass to Dataset.shuffle() to be as large as the dataset. (This might not be possible if your entire dataset doesn't fit in memory.)

Ensure that the data does not have any structure in the ordering of records by randomizing the order of the input file before training.

In addition to randomizing the order within the file, you could partition the data into several different files, and randomize the order in which you visit those files using the following:

```<code>dataset = tf.data.Dataset.list_files(shard_filenames)
dataset = dataset.shuffle(len(shard_filenames))
dataset = dataset.flat_map(lambda filename: tf.data.TFRecordDataset(filename))
# ...
</code>```

As an extension of (3), you could use Dataset.interleave() in place of Dataset.flat_map() to read multiple shards at once .

ContentLicense: CC BY-SA 3.0

Body:
I'm training a linear regression model. I use tf.contrib.data to prepare the dataset, shuffle it and serve it in batches:

  dataset = tf.contrib.data.TFRecordDataset(filename)
  dataset = dataset.map(
      _parse_function, num_threads=16, output_buffer_size=100 * batch_size)
  dataset = dataset.repeat(5)
  dataset = dataset.shuffle(buffer_size=100000)
  dataset = dataset.padded_batch(batch_size, padded_shapes=([None], [None]))
  iterator = dataset.make_initializable_iterator()
  x_inputs, y_ = iterator.get_next()

The following is our training loss:

It is very strange that at the beginning of each epoch (iteration=100k) we have a pulse in the training loss. If the training process continues, we see the same pattern at the beginning of the following epochs.

Body:
Assuming that your dataset has fewer than 100000 records, the problem could be insufficient randomness in the input shuffle. Intuitively, if the existing data are not shuffled and have some structure in their order, the training process could overfit to the records towards the end of the file, and when you restart at the beginning, the model will not perform as well on the records near the beginning of the file, and the loss will increase.

The proper solution will depend on the precise details of your dataset, but some of the following approaches might be useful:

If possible, increase the buffer_size you pass to Dataset.shuffle() to be as large as the dataset. (This might not be possible if your entire dataset doesn't fit in memory.)

Ensure that the data does not have any structure in the ordering of records by randomizing the order of the input file before training.

In addition to randomizing the order within the file, you could partition the data into several different files, and randomize the order in which you visit those files using the following:

dataset = tf.data.Dataset.list_files(shard_filenames)
dataset = dataset.shuffle(len(shard_filenames))
dataset = dataset.flat_map(lambda filename: tf.data.TFRecordDataset(filename))
# ...

As an extension of (3), you could use Dataset.interleave() in place of Dataset.flat_map() to read multiple shards at once .


问:
Mongo Java Driver searching by text index
In mongo's java driver I am using $text then $search to find things in a document however, this seems to not always yield the right results such as sometimes it will return items that don't have the searched for string. Is there a reason for this?

ANSWER

You can just escape the string and mongo won't use the delimiters. Example:

{"$text" : {"$search" : "\"<insert term here>\""}}

答:
As a quick preliminary note: You should generally give some more details and examples around your specific problem. However, this one can probably be answered without that. ;)

You are dealing with a text (!) index here. That means that there is quite some work done on the MongoDB server side when it creates the index; work that goes well beyond the sheer string.split() sort of thing that one would probably expect.

The most important things to understand is that the index will not necessarily hold all values that your text contains (e.g. common words like "and" or "the" may simply be omitted) and neither will it necessarily contain the exact words that you can read in your source data but rather word stems. A very good explanation on some of the stuff that's going on here can be found here: https://blog.codecentric.de/en/2013/01/text-search-mongodb-stemming/

There's more inside the index engine that deals with languages and special characters. But that's all reasonably well documented here and here.

Lastly, when you search for a string with spaces inside a field that's covered by a text index, the following part of the documentation is also relevant to understand:

$text will tokenize the search string using whitespace and most
  punctuation as delimiters, and perform a logical OR of all such tokens
  in the search string.

For example, you could use the following query to find all stores
  containing any terms from the list “coffee”, “shop”, and “java”:

db.stores.find( { $text: { $search: "java coffee shop" } } )

The bottom line is: There's quite a bunch of sources of potential confusion when it comes to text indexes so you want to make sure you've read up on them before you get going.

ContentLicense: CC BY-SA 4.0


问:
How to efficiently set subtract a join table in PostgreSQL?
I have the following tables:

work_units - self explanatory

workers - self explanatory

skills - every work unit requires a number of skills if you want to work on it. Every worker is proficient in a number of skills.

work_units_skills - join table

workers_skills - join table

A worker can request the next appropriate free highest priority (whatever that means) unit of work to be assigned to her.

Currently I have:

```<code>SELECT work_units.*
FROM work_units
-- some joins
WHERE NOT EXISTS (
        SELECT skill_id
        FROM work_units_skills
        WHERE work_unit_id = work_units.id

        EXCEPT

        SELECT skill_id
        FROM workers_skills
        WHERE worker_id = 1 -- the worker id that made the request
      )
-- AND a bunch of other conditions
-- ORDER BY something complex
LIMIT 1
FOR UPDATE SKIP LOCKED;
</code>```

This condition makes the query 8-10 times slower though.

Is there a better way to express that a work_units's skills should be a subset of the workers's skills or something to improve the current query?

Some more context:

The skills table is fairly small.

Both work_units and workers tend to have very few associated skills.

work_units_skills has index on work_unit_id.

I tried moving the query on workers_skills into a CTE. This gave a slight improvement (10-15%), but it's still too slow.

A work unit with no skill can be picked up by any user. Aka an empty set is a subset of every set.

答:
With Postgres, relational division can often be expressed more efficiently using arrays.

In your case I think the following will do what you want:

```<code>select *
from work_units
where id in (select work_unit_id
             from work_units_skills
             group by work_unit_id
             having array_agg(skill_id) <@ array(select skill_id
                                                 from workers_skills
                                                 where worker_id = 6))
and ... other conditions here ...
order by ...
</code>```

array_agg(skill_id) collects all skill_ids for each work_unit and compares that with the skills of a specific worker using the <@ operator ("is contained by"). That condition returns all work_unit_ids where the list of skill_ids is contained in the skills for a single worker.

In my experience this approach is usually faster then equivalent exists or intersect solutions.

Online example: http://rextester.com/WUPA82849

Body:
I have the following tables:

work_units - self explanatory

workers - self explanatory

skills - every work unit requires a number of skills if you want to work on it. Every worker is proficient in a number of skills.

work_units_skills - join table

workers_skills - join table

A worker can request the next appropriate free highest priority (whatever that means) unit of work to be assigned to her.

Currently I have:

SELECT work_units.*
FROM work_units
-- some joins
WHERE NOT EXISTS (
        SELECT skill_id
        FROM work_units_skills
        WHERE work_unit_id = work_units.id

        EXCEPT

        SELECT skill_id
        FROM workers_skills
        WHERE worker_id = 1 -- the worker id that made the request
      )
-- AND a bunch of other conditions
-- ORDER BY something complex
LIMIT 1
FOR UPDATE SKIP LOCKED;

This condition makes the query 8-10 times slower though.

Is there a better way to express that a work_units's skills should be a subset of the workers's skills or something to improve the current query?

Some more context:

The skills table is fairly small.

Both work_units and workers tend to have very few associated skills.

work_units_skills has index on work_unit_id.

I tried moving the query on workers_skills into a CTE. This gave a slight improvement (10-15%), but it's still too slow.

A work unit with no skill can be picked up by any user. Aka an empty set is a subset of every set.

Body:
With Postgres, relational division can often be expressed more efficiently using arrays.

In your case I think the following will do what you want:

select *
from work_units
where id in (select work_unit_id
             from work_units_skills
             group by work_unit_id
             having array_agg(skill_id) <@ array(select skill_id
                                                 from workers_skills
                                                 where worker_id = 6))
and ... other conditions here ...
order by ...

array_agg(skill_id) collects all skill_ids for each work_unit and compares that with the skills of a specific worker using the <@ operator ("is contained by"). That condition returns all work_unit_ids where the list of skill_ids is contained in the skills for a single worker.

In my experience this approach is usually faster then equivalent exists or intersect solutions.

Online example: http://rextester.com/WUPA82849


问:
'classmethod' object is not callable inside a metaclass's method in Python 3
I am trying to implement a metaclass that initializes class variables when a first its instance is being created. I want to keep a new magic method __load__ that should be called as a classmethod (like __new__). So I implemented it like this:

```<code>class StaticLoad(type):
    __loaded_classes = set()

    def __call__(cls, *args, **kwargs):
        if cls not in cls.__loaded_classes:
            if hasattr(cls, '__load__'):
                cls.__load__()
            cls.__loaded_classes.add(cls)
        return super().__call__(*args, **kwargs)

class BaseClass(metaclass=StaticLoad):
    s = 0

class MyClass(BaseClass):
    @classmethod
    def __load__(cls):
        print("Loading", cls.__name__, "...")
        cls.s += 1

obj1 = MyClass()
obj2 = MyClass()
print(MyClass.s)
</code>```

It works fine and gives the correct result:

```<code>Loading MyClass ...
1
</code>```

Now I want to implement the method __load__ as a classmethod by default like __new__ (without the need to type @classmethod above each time). I tried this:

```<code>class StaticLoad(type):
    __loaded_classes = set()

    def __call__(cls, *args, **kwargs):
        if cls not in cls.__loaded_classes:
            if hasattr(cls, '__load__'):
                # I try to apply classmethod routine to make
                # cls.__load__ a classmethod
                classmethod(cls.__load__)()
            cls.__loaded_classes.add(cls)
        return super().__call__(*args, **kwargs)

class BaseClass(metaclass=StaticLoad):
    s = 0

class MyClass(BaseClass):
    # @classmethod line was deleted
    def __load__(cls):
        print("Loading", cls.__name__, "...")
        cls.s += 1

obj1 = MyClass()
obj2 = MyClass()
print(MyClass.s)
</code>```

I got the error:

```<code>Traceback (most recent call last):
  File "example.py", line 22, in <module>
    obj1 = MyClass()
  File "example.py", line 7, in __call__
    classmethod(cls.__load__)()
TypeError: 'classmethod' object is not callable
</code>```

It looks like classmethod routine is correctly available only inside a class definition.

How should I improve my metaclass to make it work fine? I would like to keep the content of classes BaseClass and MyClass as I wrote above, placing all magic into StaticLoad.

答:
If you want to perform transforms on the certain methods and attributes of a class creation, you do that on the metaclass' __new__ function.

Since yu already have a metaclass, all you have to do is to implement its __new__ method to convert any __load__ methods in a classmethod:

```<code>class StaticLoad(type):
    __loaded_classes = set()

    def __new__(metacls, name, bases, namespace):
        if "__load__" in namespace and not isinstance(namespace["__load__"], classmethod):
            namespace["__load__"] = classmethod(namespace["load"])
        return super().__new__(metacls, name, bases, namespace)

    def __call__(cls, *args, **kwargs):
        if cls not in cls.__class__.__loaded_classes:
            if hasattr(cls, '__load__'):
                cls.__load__()
            type(cls).__loaded_classes.add(cls)
        return super().__call__(*args, **kwargs)
</code>```

(the other change I made was to make explict that "__loaded_classes" should be accessed on the metaclass, not on the class itself).

Body:
I am trying to implement a metaclass that initializes class variables when a first its instance is being created. I want to keep a new magic method __load__ that should be called as a classmethod (like __new__). So I implemented it like this:

class StaticLoad(type):
    __loaded_classes = set()

    def __call__(cls, *args, **kwargs):
        if cls not in cls.__loaded_classes:
            if hasattr(cls, '__load__'):
                cls.__load__()
            cls.__loaded_classes.add(cls)
        return super().__call__(*args, **kwargs)

class BaseClass(metaclass=StaticLoad):
    s = 0

class MyClass(BaseClass):
    @classmethod
    def __load__(cls):
        print("Loading", cls.__name__, "...")
        cls.s += 1

obj1 = MyClass()
obj2 = MyClass()
print(MyClass.s)

It works fine and gives the correct result:

Loading MyClass ...
1

Now I want to implement the method __load__ as a classmethod by default like __new__ (without the need to type @classmethod above each time). I tried this:

class StaticLoad(type):
    __loaded_classes = set()

    def __call__(cls, *args, **kwargs):
        if cls not in cls.__loaded_classes:
            if hasattr(cls, '__load__'):
                # I try to apply classmethod routine to make
                # cls.__load__ a classmethod
                classmethod(cls.__load__)()
            cls.__loaded_classes.add(cls)
        return super().__call__(*args, **kwargs)

class BaseClass(metaclass=StaticLoad):
    s = 0

class MyClass(BaseClass):
    # @classmethod line was deleted
    def __load__(cls):
        print("Loading", cls.__name__, "...")
        cls.s += 1

obj1 = MyClass()
obj2 = MyClass()
print(MyClass.s)

I got the error:

Traceback (most recent call last):
  File "example.py", line 22, in <module>
    obj1 = MyClass()
  File "example.py", line 7, in __call__
    classmethod(cls.__load__)()
TypeError: 'classmethod' object is not callable

It looks like classmethod routine is correctly available only inside a class definition.

How should I improve my metaclass to make it work fine? I would like to keep the content of classes BaseClass and MyClass as I wrote above, placing all magic into StaticLoad.

Body:
If you want to perform transforms on the certain methods and attributes of a class creation, you do that on the metaclass' __new__ function.

Since yu already have a metaclass, all you have to do is to implement its __new__ method to convert any __load__ methods in a classmethod:

class StaticLoad(type):
    __loaded_classes = set()

    def __new__(metacls, name, bases, namespace):
        if "__load__" in namespace and not isinstance(namespace["__load__"], classmethod):
            namespace["__load__"] = classmethod(namespace["load"])
        return super().__new__(metacls, name, bases, namespace)

    def __call__(cls, *args, **kwargs):
        if cls not in cls.__class__.__loaded_classes:
            if hasattr(cls, '__load__'):
                cls.__load__()
            type(cls).__loaded_classes.add(cls)
        return super().__call__(*args, **kwargs)

(the other change I made was to make explict that "__loaded_classes" should be accessed on the metaclass, not on the class itself).


问:
Insert data from textarea in PHP to MySQL database (also skip duplicate)
I am trying to bulk insert some data in PHP from a textarea form, and then prevent duplications from already existing data. I tried to code something but right now it just inserts everything that I insert in the textarea in same "value" in the column. But I want each line from the textarea separated in each and own column.

Here is what I have so far, and this works but it inserts the whole row:

```<code><?php
include '../includes/config.php';
if (isset($_POST["data"])) {

    $_POST["ban"] = $value;
    $line_data = explode("\n", $_POST["data"]);
    foreach ($line_data as $key => $value) {
        $checkQuery  = "SELECT ip FROM blacklist WHERE ip='" . $_POST["ip"] . "'";
        $checkResult = mysqli_query($con, $checkQuery);
        if (mysqli_num_rows($checkResult) != 0){
            // do nothing
        } else {
            $sql = "INSERT IGNORE INTO blacklist (ip) VALUES ('{$value}')";
            $result = mysqli_query($con, $sql);
        }
    }
}
?>

<form action="bulk.php" method="post">
<textarea type="text" name="data" placeholder="IP address"></textarea><br/>
<button type="submit" name="ban">Ban</button>
</form>
</code>```

So my question is, what am I doing wrong and is there good way to handle this? If so, how?

Edit: It inserts into it's own column now, but it still duplicates. Like it's still possible insert same thing many times even if data exists in database.

答: You can function explode for splitting values in field ip into lines. Save each line with ip address as separate record in your db table blacklist

Body:
I am trying to bulk insert some data in PHP from a textarea form, and then prevent duplications from already existing data. I tried to code something but right now it just inserts everything that I insert in the textarea in same "value" in the column. But I want each line from the textarea separated in each and own column.

Here is what I have so far, and this works but it inserts the whole row:

<?php
include '../includes/config.php';
if (isset($_POST["data"])) {

    $_POST["ban"] = $value;
    $line_data = explode("\n", $_POST["data"]);
    foreach ($line_data as $key => $value) {
        $checkQuery  = "SELECT ip FROM blacklist WHERE ip='" . $_POST["ip"] . "'";
        $checkResult = mysqli_query($con, $checkQuery);
        if (mysqli_num_rows($checkResult) != 0){
            // do nothing
        } else {
            $sql = "INSERT IGNORE INTO blacklist (ip) VALUES ('{$value}')";
            $result = mysqli_query($con, $sql);
        }
    }
}
?>

<form action="bulk.php" method="post">
<textarea type="text" name="data" placeholder="IP address"></textarea>

<button type="submit" name="ban">Ban</button>
</form>

So my question is, what am I doing wrong and is there good way to handle this? If so, how?

Edit: It inserts into it's own column now, but it still duplicates. Like it's still possible insert same thing many times even if data exists in database.


问:
Redirecting all 403 forbidden request to 404 page in aem
I am trying to redirect all forbidden request to 404 'not found' page.
Url I am trying to access.
    http://localhost:4503/content/mysite/home.html  (it is working fine).
But when I try to access,
    http://localhost:4503/content/mysite   (it is forbidden here).
My site is developed in adobe experience manager and I don't see any config/setting related with redirecting. So, I have to do something on web server which is Apache here.
And I am not pretty much familiar with Apache and creating rules in it.
I would like to ask if there is anything that redirect any forbidden request
to 404 not found page.</p>

答:
There are different options that you can try.

If the intent is to display some friendly message instead of the default forbidden message, you can define your own 403 error handler in AEM.
Overlay the 403.jsp at /apps/sling/servlet/errorhandler/ and add your custom html for displaying a relevant error message. HTTP response status code would still be 403 in this case.
Examples can be found in this Adobe's blog. https://helpx.adobe.com/experience-manager/6-3/sites/developing/using/customizing-errorhandler-pages.html

If you do not want the 403 HTTP status code in the response, you can try to override the status code in the aforementioned 403.jsp. In the JSP code, if the response is not already committed, you can use HttpServletResponse.setStatus API to set the 404 status code. If the response is already committed, this would not work as described in this Sling blog https://sling.apache.org/documentation/the-sling-engine/errorhandling.html

You can override it in the webserver using mod_rewrite or PHP. This SO question shows the options to achieve this.


问:
ObjectDataSource Not Binding Properly To GridView
This is probably something simple, just need some fresh eyes. It's very long, but I wanted to give full context. I'm trying to show a GridView that uses an ObjectDataSource. The ODS returns a DataTable. The DT is constructed from the query result of an MSSQL stored procedure. The problem is that my ASP BoundField is complaining at me for wanting a field that isn't in the data source...but it definitely is. When I leave out the aforementioned field, the grid shows fine, but when I press "Delete", an id of 0 is sent to my ODS, not the one that actually deletes the records, 70. I haven't tried updating yet, but I imagine that doesn't work if the other two don't. What am I doing wrong?

GridView:

```<code><asp:GridView
    AllowPaging="True"
    AllowSorting="True"
    AutoGenerateColumns="False"
    CellPadding="4"
    CssClass="table"
    DataSourceID="ExcludeODS"
    EnableViewState="True"
    ForeColor="#333333"
    GridLines="None"
    ID="ExcludeGridView"
    runat="server">
    <AlternatingRowStyle BackColor="White"></AlternatingRowStyle>
    <Columns>
        <asp:BoundField DataField="RuleKey" HeaderText="Rule Key"></asp:BoundField>
        <asp:BoundField DataField="Field" HeaderText="Field"></asp:BoundField>
        <asp:TemplateField ShowHeader="False">
            <ItemTemplate>
                <asp:LinkButton
                    runat="server"
                    CommandName="Edit"><span class="fa fa-pencil"> Edit</span>
                </asp:LinkButton>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField ShowHeader="False">
            <ItemTemplate>
                <asp:LinkButton
                    runat="server"
                    CommandName="Delete"
                    OnClientClick="if(!confirm('Are you sure you want to delete this?')){ return false; };"><span class="fa fa-trash"> Delete</span>
                </asp:LinkButton>
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
    <EditRowStyle BackColor="#2461BF"></EditRowStyle>
    <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White"></FooterStyle>
    <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White"></HeaderStyle>
    <PagerStyle HorizontalAlign="Center" BackColor="#2461BF" ForeColor="White"></PagerStyle>
    <RowStyle BackColor="#EFF3FB"></RowStyle>
    <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333"></SelectedRowStyle>
    <SortedAscendingCellStyle BackColor="#F5F7FB"></SortedAscendingCellStyle>
    <SortedAscendingHeaderStyle BackColor="#6D95E1"></SortedAscendingHeaderStyle>
    <SortedDescendingCellStyle BackColor="#E9EBEF"></SortedDescendingCellStyle>
    <SortedDescendingHeaderStyle BackColor="#4870BE"></SortedDescendingHeaderStyle>
</asp:GridView>
</code>```

ObjectDataSource (.ASPX):

```<code><asp:ObjectDataSource
    runat="server"
    ID="ExcludeODS"
    DeleteMethod="CtDeleteExcludeRules"
    InsertMethod="CtAddExcludeRules"
    SelectMethod="CtGetExcludeRules"
    TypeName="CustomerTypeRules.DAL.CtExcludeRules"
    UpdateMethod="CtUpdateExcludeRules">
    <DeleteParameters>
        <asp:Parameter Name="id" Type="Int32" ></asp:Parameter>
        <asp:Parameter Name="userId" Type="String"></asp:Parameter>
    </DeleteParameters>
    <InsertParameters>
        <asp:Parameter Name="ruleKey" Type="String"></asp:Parameter>
        <asp:Parameter Name="field" Type="String"></asp:Parameter>
        <asp:Parameter Name="userId" Type="String"></asp:Parameter>
    </InsertParameters>
    <SelectParameters>
        <asp:ControlParameter
            ControlID="RuleDropDown"
            PropertyName="SelectedValue"
            DefaultValue="null"
            Name="ruleKey"
            Type="String">
        </asp:ControlParameter>
    </SelectParameters>
    <UpdateParameters>
        <asp:Parameter Name="id" Type="Int32"></asp:Parameter>
        <asp:Parameter Name="field" Type="String"></asp:Parameter>
        <asp:Parameter Name="userId" Type="String"></asp:Parameter>
    </UpdateParameters>
</asp:ObjectDataSource>
</code>```

ObjectDataSource (.CS):

```<code>public DataTable CtGetExcludeRules(
    string ruleKey // Length: 255
)
{
    SqlConnection dbConn = new SqlConnection(_connectString);
    SqlCommand command =
        new SqlCommand
        {
            CommandText = "CT_Get_ExcludeRules",
            CommandType = CommandType.StoredProcedure,
            Connection = dbConn
        };

    command.Parameters.Add(
        "@RuleKey", SqlDbType.VarChar, 255
    ).Value = ruleKey ?? "";

    dbConn.Open();

    DataTable dt = new DataTable();
    SqlDataAdapter da = new SqlDataAdapter(command);
    da.Fill(dt);

    dbConn.Close();
    da.Dispose();

    return dt.Rows.Count > 0 ? dt : new DataTable{Columns = { "ruleKey", "field" }, Rows = { "No results" }};
}

public bool CtDeleteExcludeRules(
    int id,
    string userId // Length: 50
)
{
    using (var dbConn = new SqlConnection(_connectString))
    {
        using (var command = new SqlCommand(
            "CT_Delete_ExcludeRules", dbConn
        ))
        {
            command.CommandType = CommandType.StoredProcedure;

            command.Parameters.Add(
                "@Id", SqlDbType.Int
            ).Value = id;

            command.Parameters.Add(
                "@UserId", SqlDbType.VarChar, 50
            ).Value = userId ?? "";

            dbConn.Open();

            return command.ExecuteNonQuery() > 0;
        }
    }
}

public bool CtUpdateExcludeRules(
    int id,
    string field, // Length: 50
    string userId // Length: 50
)
{
    using (var dbConn = new SqlConnection(_connectString))
    {
        using (var command = new SqlCommand(
            "CT_Update_ExcludeRules", dbConn
        ))
        {
            command.CommandType = CommandType.StoredProcedure;

            command.Parameters.Add(
                "@Id", SqlDbType.Int
            ).Value = id;

            command.Parameters.Add(
                "@Field", SqlDbType.VarChar, 50
            ).Value = field;

            command.Parameters.Add(
                "@UserId", SqlDbType.VarChar, 50
            ).Value = System.Web.HttpContext.Current.User.Identity.Name
                      ?? "";

            dbConn.Open();

            return command.ExecuteNonQuery() > 0;
        }
    }
}
</code>```

Stored procedures:

```<code>[dbo].[CT_Get_ExcludeRules]
@RuleKey varchar(255) = ''
AS
SELECT * FROM [Interface].[dbo].[CT_ExcludeRules] WHERE RuleKey = @RuleKey;

[dbo].[CT_Delete_ExcludeRules]
@Id int,
@UserId varchar(50)
as

BEGIN TRANSACTION;
BEGIN TRY

    insert into CT_ExcludeRules_History
    select Id,RuleKey,Field,@UserId,'Delete',getdate()
    from CT_ExcludeRules
    where Id = @Id

    delete from [dbo].[CT_ExcludeRules]
    where Id = @Id

    Commit
END TRY

[CT_Update_ExcludeRules]
@Id int,
@Field varchar(50),
@UserId varchar(50)
as

BEGIN TRANSACTION;
BEGIN TRY
    Update [dbo].[CT_ExcludeRules]
    set Field = @Field
    where Id = @Id

    insert into CT_ExcludeRules_History
    select Id,RuleKey,Field,@UserId,'Update',getdate()
    from CT_ExcludeRules
    where Id = @Id

    Commit
END TRY
</code>```

Table design:

GET stored procedure example:

DataTable Rows Results View (also the same array that is retrieved by the data source's OnSelected event):

Values passed to data source after clicking "Delete":

Trying to add an Id column to the GridView gives me this error message:

A field or property with the name 'Id' was not found on the selected
  data source.

I don't need an id column, I just want to delete and update like a normal GridView!

RESOLUTION:

Thanks to user "sea-charp" below for seeing what was missing. I needed to replace { "ruleKey", "field" } with { "id", "ruleKey", "field" } in order for my data source to recognize the "Id" property. Once that was recognized, I was able to add "Id" in the DataKeyNames attribute of my GridView, which fully enabled my deletion method via the proper Id of 70 instead of 0.

答:
Instead of this :

```<code>command.Parameters.Add(
        "@RuleKey", SqlDbType.VarChar, 255
    ).Value = ruleKey ?? "";
</code>```

Try this

```<code>command.Parameters.Add("@RuleKey", SqlDbType.VarChar, 255);
command.Parameters("@RuleKey").Value = ruleKey ?? "";
</code>```

Looks like you're getting the error because you have this as part of your return syntax:

```<code>DataTable{Columns = { "ruleKey", "field" }, Rows = { "No results" }};
</code>```

... which returns a table with no ID when there are no results - possibly because of the command parameter syntax you're using.

Body:
This is probably something simple, just need some fresh eyes. It's very long, but I wanted to give full context. I'm trying to show a GridView that uses an ObjectDataSource. The ODS returns a DataTable. The DT is constructed from the query result of an MSSQL stored procedure. The problem is that my ASP BoundField is complaining at me for wanting a field that isn't in the data source...but it definitely is. When I leave out the aforementioned field, the grid shows fine, but when I press "Delete", an id of 0 is sent to my ODS, not the one that actually deletes the records, 70. I haven't tried updating yet, but I imagine that doesn't work if the other two don't. What am I doing wrong?

GridView:

<asp:GridView
    AllowPaging="True"
    AllowSorting="True"
    AutoGenerateColumns="False"
    CellPadding="4"
    CssClass="table"
    DataSourceID="ExcludeODS"
    EnableViewState="True"
    ForeColor="#333333"
    GridLines="None"
    ID="ExcludeGridView"
    runat="server">
    <AlternatingRowStyle BackColor="White"></AlternatingRowStyle>
    <Columns>
        <asp:BoundField DataField="RuleKey" HeaderText="Rule Key"></asp:BoundField>
        <asp:BoundField DataField="Field" HeaderText="Field"></asp:BoundField>
        <asp:TemplateField ShowHeader="False">
            <ItemTemplate>
                <asp:LinkButton
                    runat="server"
                    CommandName="Edit"> Edit
                </asp:LinkButton>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField ShowHeader="False">
            <ItemTemplate>
                <asp:LinkButton
                    runat="server"
                    CommandName="Delete"
                    OnClientClick="if(!confirm('Are you sure you want to delete this?')){ return false; };"> Delete
                </asp:LinkButton>
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
    <EditRowStyle BackColor="#2461BF"></EditRowStyle>
    <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White"></FooterStyle>
    <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White"></HeaderStyle>
    <PagerStyle HorizontalAlign="Center" BackColor="#2461BF" ForeColor="White"></PagerStyle>
    <RowStyle BackColor="#EFF3FB"></RowStyle>
    <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333"></SelectedRowStyle>
    <SortedAscendingCellStyle BackColor="#F5F7FB"></SortedAscendingCellStyle>
    <SortedAscendingHeaderStyle BackColor="#6D95E1"></SortedAscendingHeaderStyle>
    <SortedDescendingCellStyle BackColor="#E9EBEF"></SortedDescendingCellStyle>
    <SortedDescendingHeaderStyle BackColor="#4870BE"></SortedDescendingHeaderStyle>
</asp:GridView>

ObjectDataSource (.ASPX):

<asp:ObjectDataSource
    runat="server"
    ID="ExcludeODS"
    DeleteMethod="CtDeleteExcludeRules"
    InsertMethod="CtAddExcludeRules"
    SelectMethod="CtGetExcludeRules"
    TypeName="CustomerTypeRules.DAL.CtExcludeRules"
    UpdateMethod="CtUpdateExcludeRules">
    <DeleteParameters>
        <asp:Parameter Name="id" Type="Int32" ></asp:Parameter>
        <asp:Parameter Name="userId" Type="String"></asp:Parameter>
    </DeleteParameters>
    <InsertParameters>
        <asp:Parameter Name="ruleKey" Type="String"></asp:Parameter>
        <asp:Parameter Name="field" Type="String"></asp:Parameter>
        <asp:Parameter Name="userId" Type="String"></asp:Parameter>
    </InsertParameters>
    <SelectParameters>
        <asp:ControlParameter
            ControlID="RuleDropDown"
            PropertyName="SelectedValue"
            DefaultValue="null"
            Name="ruleKey"
            Type="String">
        </asp:ControlParameter>
    </SelectParameters>
    <UpdateParameters>
        <asp:Parameter Name="id" Type="Int32"></asp:Parameter>
        <asp:Parameter Name="field" Type="String"></asp:Parameter>
        <asp:Parameter Name="userId" Type="String"></asp:Parameter>
    </UpdateParameters>
</asp:ObjectDataSource>

ObjectDataSource (.CS):

public DataTable CtGetExcludeRules(
    string ruleKey // Length: 255
)
{
    SqlConnection dbConn = new SqlConnection(_connectString);
    SqlCommand command =
        new SqlCommand
        {
            CommandText = "CT_Get_ExcludeRules",
            CommandType = CommandType.StoredProcedure,
            Connection = dbConn
        };

    command.Parameters.Add(
        "@RuleKey", SqlDbType.VarChar, 255
    ).Value = ruleKey ?? "";

    dbConn.Open();

    DataTable dt = new DataTable();
    SqlDataAdapter da = new SqlDataAdapter(command);
    da.Fill(dt);

    dbConn.Close();
    da.Dispose();

    return dt.Rows.Count > 0 ? dt : new DataTable{Columns = { "ruleKey", "field" }, Rows = { "No results" }};
}

public bool CtDeleteExcludeRules(
    int id,
    string userId // Length: 50
)
{
    using (var dbConn = new SqlConnection(_connectString))
    {
        using (var command = new SqlCommand(
            "CT_Delete_ExcludeRules", dbConn
        ))
        {
            command.CommandType = CommandType.StoredProcedure;

            command.Parameters.Add(
                "@Id", SqlDbType.Int
            ).Value = id;

            command.Parameters.Add(
                "@UserId", SqlDbType.VarChar, 50
            ).Value = userId ?? "";

            dbConn.Open();

            return command.ExecuteNonQuery() > 0;
        }
    }
}

public bool CtUpdateExcludeRules(
    int id,
    string field, // Length: 50
    string userId // Length: 50
)
{
    using (var dbConn = new SqlConnection(_connectString))
    {
        using (var command = new SqlCommand(
            "CT_Update_ExcludeRules", dbConn
        ))
        {
            command.CommandType = CommandType.StoredProcedure;

            command.Parameters.Add(
                "@Id", SqlDbType.Int
            ).Value = id;

            command.Parameters.Add(
                "@Field", SqlDbType.VarChar, 50
            ).Value = field;

            command.Parameters.Add(
                "@UserId", SqlDbType.VarChar, 50
            ).Value = System.Web.HttpContext.Current.User.Identity.Name
                      ?? "";

            dbConn.Open();

            return command.ExecuteNonQuery() > 0;
        }
    }
}

Stored procedures:

[dbo].[CT_Get_ExcludeRules]
@RuleKey varchar(255) = ''
AS
SELECT * FROM [Interface].[dbo].[CT_ExcludeRules] WHERE RuleKey = @RuleKey;

[dbo].[CT_Delete_ExcludeRules]
@Id int,
@UserId varchar(50)
as

BEGIN TRANSACTION;
BEGIN TRY

    insert into CT_ExcludeRules_History
    select Id,RuleKey,Field,@UserId,'Delete',getdate()
    from CT_ExcludeRules
    where Id = @Id

    delete from [dbo].[CT_ExcludeRules]
    where Id = @Id

    Commit
END TRY

[CT_Update_ExcludeRules]
@Id int,
@Field varchar(50),
@UserId varchar(50)
as

BEGIN TRANSACTION;
BEGIN TRY
    Update [dbo].[CT_ExcludeRules]
    set Field = @Field
    where Id = @Id

    insert into CT_ExcludeRules_History
    select Id,RuleKey,Field,@UserId,'Update',getdate()
    from CT_ExcludeRules
    where Id = @Id

    Commit
END TRY

Table design:

GET stored procedure example:

DataTable Rows Results View (also the same array that is retrieved by the data source's OnSelected event):

Values passed to data source after clicking "Delete":

Trying to add an Id column to the GridView gives me this error message:

A field or property with the name 'Id' was not found on the selected
  data source.

I don't need an id column, I just want to delete and update like a normal GridView!

RESOLUTION:

Thanks to user "sea-charp" below for seeing what was missing. I needed to replace { "ruleKey", "field" } with { "id", "ruleKey", "field" } in order for my data source to recognize the "Id" property. Once that was recognized, I was able to add "Id" in the DataKeyNames attribute of my GridView, which fully enabled my deletion method via the proper Id of 70 instead of 0.

Body:
Instead of this :

command.Parameters.Add(
        "@RuleKey", SqlDbType.VarChar, 255
    ).Value = ruleKey ?? "";

Try this

command.Parameters.Add("@RuleKey", SqlDbType.VarChar, 255);
command.Parameters("@RuleKey").Value = ruleKey ?? "";

Looks like you're getting the error because you have this as part of your return syntax:

DataTable{Columns = { "ruleKey", "field" }, Rows = { "No results" }};

... which returns a table with no ID when there are no results - possibly because of the command parameter syntax you're using.


问:
Selenium/testNG: How to run your test based on class priority and not on your method priorily from the XML file
If have the following:

Class A
{
  Method M(priority = 2)
}

Class B
{
  Method M(priority = 1)
}
```

<p>Then <code>Class B</code> is going to be executed before <code>Class A</code>. How can I execute <code>Class A</code> first?</p>

<p>The XML file that I am using is:</p>

<pre class="lang-xml prettyprint-override"><code><classes>
  <class name="com.Users.Admin_ManageUsers_AR"/>
  <class name="com.Users.Admin_ManageUsers_AR"/>
</classes>
</code>```

答:
I would go with group-by-instances as well as answered by others.

Alternatively, you could use groups and dependencies like this example in the documentation

```<code><test name="ManageUsersTest">
  <groups>
    <dependencies>
      <group name="c" depends-on="a  b" />
      <group name="z" depends-on="c" />
    </dependencies>
  </groups>
</test>
</code>```

The depends-on attribute contains a space-separated list of groups.

This gives you more control in case you have dependencies across classes.

Body:
If have the following:

Class A
{
  Method M(priority = 2)
}

Class B
{
  Method M(priority = 1)
}

Then Class B is going to be executed before Class A. How can I execute Class A first?

The XML file that I am using is:

<classes>
  <class name="com.Users.Admin_ManageUsers_AR"/>
  <class name="com.Users.Admin_ManageUsers_AR"/>
</classes>

Body:
I would go with group-by-instances as well as answered by others.

Alternatively, you could use groups and dependencies like this example in the documentation

<test name="ManageUsersTest">
  <groups>
    <dependencies>
      <group name="c" depends-on="a  b" />
      <group name="z" depends-on="c" />
    </dependencies>
  </groups>
</test>

The depends-on attribute contains a space-separated list of groups.

This gives you more control in case you have dependencies across classes.


问:
Length of time representation in Go
Under Unix, I'm working on a program that needs to behave differently depending on whether time is 32-bit (will wrap in 2038) or 64-bit.

I presume Go time is not magic and will wrap in 2038 on a platform with a 32-bit time_t.  If this is false and it is somehow always 64-bit, clue me in because that will prevent much grief.

What's the simplest way in Go to write a test for the platform's time_t size?  Is there any way simpler than the obvious hack with cgo?

答:
Ordinarily, time.Time uses 63 bits to represent wall clock seconds elapsed since January 1, year 1 00:00:00 UTC, up through 219250468-12-04 15:30:09.147483647 +0000 UTC. For example,

```<code>package main

import (
    "fmt"
    "time"
)

func main() {
    var t time.Time
    fmt.Println(t)
    t = time.Unix(1<<63-1, 1<<31-1)
    fmt.Println(t)
}
</code>```

Playground: https://play.golang.org/p/QPs1m6eMPH

Output:

```<code>0001-01-01 00:00:00 +0000 UTC
219250468-12-04 15:30:09.147483647 +0000 UTC
</code>```

If time.Time is monotonic (derived from time.Now()), time.Time uses 33 bits to represent wall clock seconds, covering the years 1885 through 2157.

References:

Package time

Proposal: Monotonic Elapsed Time Measurements in Go

Title: Length of time representation in Go

Body:
Ordinarily, time.Time uses 63 bits to represent wall clock seconds elapsed since January 1, year 1 00:00:00 UTC, up through 219250468-12-04 15:30:09.147483647 +0000 UTC. For example,

package main

import (
    "fmt"
    "time"
)

func main() {
    var t time.Time
    fmt.Println(t)
    t = time.Unix(1<<63-1, 1<<31-1)
    fmt.Println(t)
}

Playground: https://play.golang.org/p/QPs1m6eMPH

Output:

0001-01-01 00:00:00 +0000 UTC
219250468-12-04 15:30:09.147483647 +0000 UTC

If time.Time is monotonic (derived from time.Now()), time.Time uses 33 bits to represent wall clock seconds, covering the years 1885 through 2157.

References:

Package time

Proposal: Monotonic Elapsed Time Measurements in Go


问:
Can't assign array element to class variable while overloading "=" operator
I am quite new in C++ programming, so maybe that's why I can't figure out why this assignment is not working.
In my class, I want to overload "=" operator.
I have specified a function, that outputs variables as an array. In overloading, I want to assign those variables to new object.

```<code> obj_new = obj_with_variables
</code>```

overloading:

```<code>  obj_new_x=obj_with_values_parameters()[0];
  obj_new_y=obj_with_values_parameters()[1];
</code>```

Here is a code:

```<code>// Test1.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include "string"

using namespace std;

class Vector2D
{
public:
Vector2D()
{

}
Vector2D(int& a, int& b)
    :x(a), y(b)
{

}
void Drukuj()
{
    cout << "wektor [" << x << ',' << y << "] \n";
}
void Wspolrzedne(int&a, int&b)
{
    x = a;
    y = b;
}
int* Wspolrzedne()
{
    int tab[2] = { x,y };
    return tab;
}
void operator = (Vector2D& obj)
{
    int* a = obj.Wspolrzedne();
    cout << a[0] << "\n";
    x = a[0];
    cout << x << " what? \n";
    y = a[1];
}

private:
int x, y;

};

int main()
{
int x1 = 2, x2 = 3;
Vector2D wektor(x1, x2);
wektor.Drukuj();
Vector2D wektor2;
wektor2 = wektor;
wektor2.Drukuj();
wektor.Drukuj();

return 0;
}
</code>```

The problem is that it assigns some strange values. However, if I don't use a reference, but declare 2 int values (j,k) and assign array element to them [0,1], it works fine.
Also, when using static numbers (for example, instead of a[0] ; use "2") it works fine too.

What is going on?

I would be glad if somebody could point me to right answer/ resources.

Regards,

答:
Your code has undefined behavior because operator= is accessing invalid data.  Wspolrzedne() is returning a pointer to a local variable tab that goes out of scope when Wspolrzedne() exits, thus the a pointer used in operator= is not pointing at valid data.

If you want Wspolrzedne() to return multiple values, you need to have it return (by value) an instance of a struct or class to hold them.  Try something more like this:

```<code>#include "stdafx.h"
#include <iostream>
#include <string>

using namespace std;

struct Coordinate {
    int x;
    int y;
};

class Vector2D
{
public:
    Vector2D()
        : x(0), y(0)
    {
    }

    Vector2D(int a, int b)
        : x(a), y(b)
    {
    }

    Vector2D(const Coordinate &c)
        : x(c.x), y(c.y)
    {
    }

    Vector2D(const Vector2D &src)
        : x(src.x), y(src.y)
    {
    }

    void Drukuj()
    {
        cout << "wektor [" << x << ',' << y << "] \n";
    }

    void Wspolrzedne(int a, int b)
    {
        x = a;
        y = b;
    }

    void Wspolrzedne(const Coordinate &c)
    {
        x = c.x;
        y = c.y;
    }

    Coordinate Wspolrzedne()
    {
        Coordinate c = { x, y };
        return c;
    }

    Vector2D& operator=(const Vector2D &obj)
    {
        Coordinate c = obj.Wspolrzedne();
        cout << c.x << ',' << c.y << "\n";
        Wspolrzedne(c);
        return *this;
    }

private:
    int x;
    int y;
};
</code>```

On the other hand, there is no real reason to even have operator= call Wspolrzedne() to get the coordinates at all, when it can just access obj.x and obj.y directly instead:

```<code>Vector2D& operator=(const Vector2D &obj)
{
    x = obj.x;
    y = obj.y;
    return *this;
}
</code>```

In which case, you can simply eliminate your operator= altogether, and let the compiler provide a default-generated implementation that does the exact same thing for you.

Body:
I am quite new in C++ programming, so maybe that's why I can't figure out why this assignment is not working.
In my class, I want to overload "=" operator.
I have specified a function, that outputs variables as an array. In overloading, I want to assign those variables to new object.

 obj_new = obj_with_variables

overloading:

  obj_new_x=obj_with_values_parameters()[0];
  obj_new_y=obj_with_values_parameters()[1];

Here is a code:

// Test1.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include "string"

using namespace std;

class Vector2D
{
public:
Vector2D()
{

}
Vector2D(int& a, int& b)
    :x(a), y(b)
{

}
void Drukuj()
{
    cout << "wektor [" << x << ',' << y << "] \n";
}
void Wspolrzedne(int&a, int&b)
{
    x = a;
    y = b;
}
int* Wspolrzedne()
{
    int tab[2] = { x,y };
    return tab;
}
void operator = (Vector2D& obj)
{
    int* a = obj.Wspolrzedne();
    cout << a[0] << "\n";
    x = a[0];
    cout << x << " what? \n";
    y = a[1];
}

private:
int x, y;

};

int main()
{
int x1 = 2, x2 = 3;
Vector2D wektor(x1, x2);
wektor.Drukuj();
Vector2D wektor2;
wektor2 = wektor;
wektor2.Drukuj();
wektor.Drukuj();

return 0;
}

The problem is that it assigns some strange values. However, if I don't use a reference, but declare 2 int values (j,k) and assign array element to them [0,1], it works fine.
Also, when using static numbers (for example, instead of a[0] ; use "2") it works fine too.

What is going on?

I would be glad if somebody could point me to right answer/ resources.

Regards,

Body:
Your code has undefined behavior because operator= is accessing invalid data.  Wspolrzedne() is returning a pointer to a local variable tab that goes out of scope when Wspolrzedne() exits, thus the a pointer used in operator= is not pointing at valid data.

If you want Wspolrzedne() to return multiple values, you need to have it return (by value) an instance of a struct or class to hold them.  Try something more like this:

#include "stdafx.h"
#include <iostream>
#include <string>

using namespace std;

struct Coordinate {
    int x;
    int y;
};

class Vector2D
{
public:
    Vector2D()
        : x(0), y(0)
    {
    }

    Vector2D(int a, int b)
        : x(a), y(b)
    {
    }

    Vector2D(const Coordinate &c)
        : x(c.x), y(c.y)
    {
    }

    Vector2D(const Vector2D &src)
        : x(src.x), y(src.y)
    {
    }

    void Drukuj()
    {
        cout << "wektor [" << x << ',' << y << "] \n";
    }

    void Wspolrzedne(int a, int b)
    {
        x = a;
        y = b;
    }

    void Wspolrzedne(const Coordinate &c)
    {
        x = c.x;
        y = c.y;
    }

    Coordinate Wspolrzedne()
    {
        Coordinate c = { x, y };
        return c;
    }

    Vector2D& operator=(const Vector2D &obj)
    {
        Coordinate c = obj.Wspolrzedne();
        cout << c.x << ',' << c.y << "\n";
        Wspolrzedne(c);
        return *this;
    }

private:
    int x;
    int y;
};

On the other hand, there is no real reason to even have operator= call Wspolrzedne() to get the coordinates at all, when it can just access obj.x and obj.y directly instead:

Vector2D& operator=(const Vector2D &obj)
{
    x = obj.x;
    y = obj.y;
    return *this;
}

In which case, you can simply eliminate your operator= altogether, and let the compiler provide a default-generated implementation that does the exact same thing for you.


问:
Rmarkdown Image Skips Ahead of Text
I am putting together an Rmarkdown PDF document with the following YAML settings:

```<code>---
output:
  pdf_document:
    fig_caption: true
    fig_crop: true
    toc_depth: 3
  header-includes:
  - \usepackage{hyperref}
 ---
</code>```

Within the body of the document I've inserted a few PNG images, using the following syntax

```<code>Paragraph 1..........

![Caption](path/image.png)

Paragraph 2....
</code>```

And when the document is rendered, the image appears as expected within the text, between Paragraph 1 and Paragraph 2. However, I am getting some unpredictable results where the rendered image appears after Paragraph 2 in some cases and I can't manage to solve it.

答:
One option is to add

```<code>\newpage
</code>```

to act in a similar way as the Floatbarrier. It is not to elegant but seems to work.

For greater clarity consider the example from above:

```<code>Paragraph 1..........

![Caption](path/image.png)

Paragraph 2....
</code>```

To avoid the image to move in front of the second paragraph, you could do the following:

```<code>Paragraph 1..........

![Caption](path/image.png)

\newpage

Paragraph 2....
</code>```

Title: Rmarkdown Image Skips Ahead of Text

Body:
I am putting together an Rmarkdown PDF document with the following YAML settings:

---
output:
  pdf_document:
    fig_caption: true
    fig_crop: true
    toc_depth: 3
  header-includes:
  - \usepackage{hyperref}
 ---

Within the body of the document I've inserted a few PNG images, using the following syntax

Paragraph 1..........

![Caption](path/image.png)

Paragraph 2....

And when the document is rendered, the image appears as expected within the text, between Paragraph 1 and Paragraph 2. However, I am getting some unpredictable results where the rendered image appears after Paragraph 2 in some cases and I can't manage to solve it.

Body:
One option is to add

\newpage

to act in a similar way as the Floatbarrier. It is not to elegant but seems to work.

For greater clarity consider the example from above:

Paragraph 1..........

![Caption](path/image.png)

Paragraph 2....

To avoid the image to move in front of the second paragraph, you could do the following:

Paragraph 1..........

![Caption](path/image.png)

\newpage

Paragraph 2....


问:
How to configure guava cache to remove item after a read?
I would like to remove (invalidate) an item after it was read from a cache.

So item should be present in a cache until a first read.

I've tried adding expireAfterAccess(0, TimeUnit.NANOSECONDS) but then cache is not populated.

Is there any way to use guava cache in such manner or do I need to invalidate item manually after a read?

答:
This won't work. "Access" means "read or write access" and when it expires immediately after read, then it also expires immediately after write.

You can remove the entry manually. You can use the asMap() view in order to do it in a single access:

```<code>String getAndClear(String key) {
    String[] result = {null};
    cache.asMap().compute(key, (k, v) ->
        result[0] = v;
        return null;
    });
    return result[0];
}
</code>```

You could switch to Caffeine, which is sort of more advanced Guava cache and offers very flexible expireAfter(Expiry).

However, I don't think, that what you want is a job for a cache. As nonces should never be repeated, I can't imagine any reason to store them. Usually, you generate and use them immediately.

You may be doing it wrong and you may want to elaborate, so that a possible security problem gets avoided.

Body:
This won't work. "Access" means "read or write access" and when it expires immediately after read, then it also expires immediately after write.

You can remove the entry manually. You can use the asMap() view in order to do it in a single access:

String getAndClear(String key) {
    String[] result = {null};
    cache.asMap().compute(key, (k, v) ->
        result[0] = v;
        return null;
    });
    return result[0];
}

You could switch to Caffeine, which is sort of more advanced Guava cache and offers very flexible expireAfter(Expiry).

However, I don't think, that what you want is a job for a cache. As nonces should never be repeated, I can't imagine any reason to store them. Usually, you generate and use them immediately.

You may be doing it wrong and you may want to elaborate, so that a possible security problem gets avoided.


问:
Can Azure Data Factory write to FTP
I want to write the output of pipeline to an FTP folder. ADF seems to support on-premises file but not FTP folder.

How can I write the output in text format to an FTP folder?

答:
As a lighter weight approach to custom activities (certainly the better option for heavy work).

You may wish to consider using azure functions to write to ftp (note there is a time out when using a consumption plan - not in other plans, so it will depend on how big the files are).

https://learn.microsoft.com/en-us/azure/azure-functions/functions-create-storage-blob-triggered-function

You could instruct data factory to write to a intermediary blob storage.
And use blob storage triggers in azure functions to upload them as soon as they appear in blob storage.

Or alternatively, write to blob storage. And then use a timer in logic apps to upload from blob storage to ftp. Logic Apps hide a tremendous amount of power behind there friendly exterior.

Title: Can Azure Data Factory write to FTP


问:
Form Validation jQuery plugin success.form.fv event not working

I am trying to build a dynamic popup that allows the user to edit data in a datatable without redirecting the page. I am using NodeJS with jQuery 'modal' library for the popup and 'formvalidation' library to validate and submit the data. (Note: This is not the same library as jquery validate).

Here's a demo of exactly what I am attempting to accomplish.

http://formvalidation.io/examples/loading-saving-data-modal/

I got most of the code working, I was able to display the modal window, passing in data and the validation works properly, too. The problem is that the success.form.fv event is not being triggered, the dialog just closes.

```<code>script.
    $(document).ready(function () {
      $('#editFilepathForm')
        .formValidation({
          framework: 'bootstrap',
          icon: {
            valid: 'glyphicon glyphicon-ok',
            invalid: 'glyphicon glyphicon-remove',
            validating: 'glyphicon glyphicon-refresh'
          },
          fields: {
            id: {
              validators: {
                notEmpty: {
                  message: 'ID is required'
                }
              }
            },
            edited_filepath: {
              validators: {
                notEmpty: {
                  message: 'Edited Filepath is required'
                },
                regexp: {
                    regexp: /^[a-zA-Z\s]+$/,
                    message: 'The full name can only consist of alphabetical characters'
                }
              }
            },
            edited_filename: {
              validators: {
                notEmpty: {
                  message: 'Edited Filename is required'
                },
                regexp: {
                    regexp: /^[a-zA-Z\s]+$/,
                    message: 'The full name can only consist of alphabetical characters'
                }
              }
            }
          }
        })
//THIS EVENT IS NOT TRIGGERING AT ALL. ALERT MESSAGE DOES NOT APPEAR. THE BOX JUST CLOSES AFTER SUCCESSFUL VALIDATION.
        .on('success.form.fv', function (e) {
          alert('success');
          // Save the form data via an Ajax request
          e.preventDefault();

          var $form = $(e.target),
            id = $form.find('[name="id"]').val();

            // Hide the dialog
            $form.parents('.bootbox').modal('hide');

            // You can inform the user that the data is updated successfully
            // by highlighting the row or showing a message box
            bootbox.alert('The user profile is updated');
          //});
        });

      $('.editButton').on('click', function () {
          var id = $(this).attr('data-id');
          var requested_filepath = $(this).attr('data-requested-filepath');
          var requested_filename = $(this).attr('data-requested-filename');

          /*Set original requested values to display in modal form window*/
          $('#editFilepathForm')
            .find('[name="id"]').html(id).end()
            .find('[name="requested_filepath"]').html(requested_filepath).end()
            .find('[name="requested_filename"]').html(requested_filename).end()
            .find('[name="edited_filepath"]').val(requested_filepath).end()
            .find('[name="edited_filename"]').val(requested_filename).end()

          // Show the dialog
          bootbox
            .dialog({
              title: 'Edit Requested Filepath',
              message: $('#editFilepathForm'),
              show: false // We will show it manually later
            })
            .on('shown.bs.modal', function () {
              $('#editFilepathForm')
                .show() // Show the login form
                .formValidation('resetForm'); // Reset form
            })
            .on('hide.bs.modal', function (e) {
              // Bootbox will remove the modal (including the body which contains the login form)
              // after hiding the modal
              // Therefor, we need to backup the form
              $('#editFilepathForm').hide().appendTo('body');
            })
            .modal('show');
        //});
      });
    });
</code>```

答:
I was able to resolve the issue by adding the 'excluded' property as explained in the documentation.

http://formvalidation.io/examples/modal/

Body:
I am trying to build a dynamic popup that allows the user to edit data in a datatable without redirecting the page. I am using NodeJS with jQuery 'modal' library for the popup and 'formvalidation' library to validate and submit the data. (Note: This is not the same library as jquery validate).

Here's a demo of exactly what I am attempting to accomplish.

http://formvalidation.io/examples/loading-saving-data-modal/

I got most of the code working, I was able to display the modal window, passing in data and the validation works properly, too. The problem is that the success.form.fv event is not being triggered, the dialog just closes.

script.
    $(document).ready(function () {
      $('#editFilepathForm')
        .formValidation({
          framework: 'bootstrap',
          icon: {
            valid: 'glyphicon glyphicon-ok',
            invalid: 'glyphicon glyphicon-remove',
            validating: 'glyphicon glyphicon-refresh'
          },
          fields: {
            id: {
              validators: {
                notEmpty: {
                  message: 'ID is required'
                }
              }
            },
            edited_filepath: {
              validators: {
                notEmpty: {
                  message: 'Edited Filepath is required'
                },
                regexp: {
                    regexp: /^[a-zA-Z\s]+$/,
                    message: 'The full name can only consist of alphabetical characters'
                }
              }
            },
            edited_filename: {
              validators: {
                notEmpty: {
                  message: 'Edited Filename is required'
                },
                regexp: {
                    regexp: /^[a-zA-Z\s]+$/,
                    message: 'The full name can only consist of alphabetical characters'
                }
              }
            }
          }
        })
//THIS EVENT IS NOT TRIGGERING AT ALL. ALERT MESSAGE DOES NOT APPEAR. THE BOX JUST CLOSES AFTER SUCCESSFUL VALIDATION.
        .on('success.form.fv', function (e) {
          alert('success');
          // Save the form data via an Ajax request
          e.preventDefault();

          var $form = $(e.target),
            id = $form.find('[name="id"]').val();

            // Hide the dialog
            $form.parents('.bootbox').modal('hide');

            // You can inform the user that the data is updated successfully
            // by highlighting the row or showing a message box
            bootbox.alert('The user profile is updated');
          //});
        });

      $('.editButton').on('click', function () {
          var id = $(this).attr('data-id');
          var requested_filepath = $(this).attr('data-requested-filepath');
          var requested_filename = $(this).attr('data-requested-filename');

          /*Set original requested values to display in modal form window*/
          $('#editFilepathForm')
            .find('[name="id"]').html(id).end()
            .find('[name="requested_filepath"]').html(requested_filepath).end()
            .find('[name="requested_filename"]').html(requested_filename).end()
            .find('[name="edited_filepath"]').val(requested_filepath).end()
            .find('[name="edited_filename"]').val(requested_filename).end()

          // Show the dialog
          bootbox
            .dialog({
              title: 'Edit Requested Filepath',
              message: $('#editFilepathForm'),
              show: false // We will show it manually later
            })
            .on('shown.bs.modal', function () {
              $('#editFilepathForm')
                .show() // Show the login form
                .formValidation('resetForm'); // Reset form
            })
            .on('hide.bs.modal', function (e) {
              // Bootbox will remove the modal (including the body which contains the login form)
              // after hiding the modal
              // Therefor, we need to backup the form
              $('#editFilepathForm').hide().appendTo('body');
            })
            .modal('show');
        //});
      });
    });


问:
firestore array-like data structure indexing limitation
In the firestore documentation, there is a description below

Indexing limits - A single document can have only 20,000 properties in
  order to use Cloud Firestore built-in indexes. If your array-like data
  structure grows to tens of thousands of members, you may run into this
  limit.

https://cloud.google.com/firestore/docs/solutions/arrays

I want to know how I can interpret the description.
Which of two patterns meet the limitation?

```<code><pattern 1: categories in one document above 20,000>
    doc1
     - id:111
     - categories: {aaaa:true, aaab:false, aaac:true, aaad: false, aaae:true, aaaf:true, aaag:true, aaah:true, aaai:true, aaaj:true, ,,,,,,,,,,, }
</code>```

another pattern

```<code><pattern 2:  categories in one document is a few but as a collection of document number of categories above 20,000>
    doc_1
    - id:111
    categories{aaaa:true, aaab:false, aaac:true, only several element}
    doc_2
    - id:111
    categories{aaad:true, aaae:false, aaaf:true, only several element}
    doc_3
    - id:111
    categories{aaag:true, aaah:false, aaai:true, only several element}
</code>```

I believe that pattern 1 reach the limit, but is pattern 2 reach the limit?

答:
The limit is on the total number of properties, so it's possible that both patterns could hit the 20,000 limit.

Here are some examples of counting properties that may help:

This document has two properties: a and b.c

```<code>{
  a: "foo",
  b: {
   c: "bar"
  }
}
</code>```

This document has four properties: a, b, b.c, d

```<code>{
  a: "foo",
  b: {
   c: "bar",
  },
  d: ["quz", "qaz"]
}
</code>```

And this document has four as well:

```<code>{
  a: "foo",
  b: {
   c: "bar",
  },
  d: ["quz", "qaz", "apple", "banana"]
}
</code>```

This document has five:

```<code>{
  a: "foo",
  b: {
   c: "bar",
  },
  d: ["quz", "qaz"],
  e: ["apple", "banana"]
}
</code>```

So it's not about the length of any single array or how deeply nested things are, it's about the total number of queryable values.

EDIT 03/05/18: I was wrong before when I said that array members counted separately against the index.  They do not, that was something we had in place when Firestore was in Alpha that never applied in a public release.

Body:
In the firestore documentation, there is a description below

Indexing limits - A single document can have only 20,000 properties in
  order to use Cloud Firestore built-in indexes. If your array-like data
  structure grows to tens of thousands of members, you may run into this
  limit.

https://cloud.google.com/firestore/docs/solutions/arrays

I want to know how I can interpret the description.
Which of two patterns meet the limitation?

<pattern 1: categories in one document above 20,000>
    doc1
     - id:111
     - categories: {aaaa:true, aaab:false, aaac:true, aaad: false, aaae:true, aaaf:true, aaag:true, aaah:true, aaai:true, aaaj:true, ,,,,,,,,,,, }

another pattern

<pattern 2:  categories in one document is a few but as a collection of document number of categories above 20,000>
    doc_1
    - id:111
    categories{aaaa:true, aaab:false, aaac:true, only several element}
    doc_2
    - id:111
    categories{aaad:true, aaae:false, aaaf:true, only several element}
    doc_3
    - id:111
    categories{aaag:true, aaah:false, aaai:true, only several element}

I believe that pattern 1 reach the limit, but is pattern 2 reach the limit?

Body:
The limit is on the total number of properties, so it's possible that both patterns could hit the 20,000 limit.

Here are some examples of counting properties that may help:

This document has two properties: a and b.c

{
  a: "foo",
  b: {
   c: "bar"
  }
}

This document has four properties: a, b, b.c, d

{
  a: "foo",
  b: {
   c: "bar",
  },
  d: ["quz", "qaz"]
}

And this document has four as well:

{
  a: "foo",
  b: {
   c: "bar",
  },
  d: ["quz", "qaz", "apple", "banana"]
}

This document has five:

{
  a: "foo",
  b: {
   c: "bar",
  },
  d: ["quz", "qaz"],
  e: ["apple", "banana"]
}

So it's not about the length of any single array or how deeply nested things are, it's about the total number of queryable values.

EDIT 03/05/18: I was wrong before when I said that array members counted separately against the index.  They do not, that was something we had in place when Firestore was in Alpha that never applied in a public release.


问:
How do I add an integer value with javascript (jquery) to a value that's returning a string?
I have a simple html block like:

```<code><span id="replies">8</span>
</code>```

Using jquery I'm trying to add a 1 to the value (8).

```<code>var currentValue = $("#replies").text();
var newValue = currentValue + 1;
$("replies").text(newValue);
</code>```

What's happening is it is appearing like:

81

then

811

not 9, which would be the correct answer.  What am I doing wrong?

答:
In regards to the octal misinterpretation of .js - I just used this...

```<code>parseInt(parseFloat(nv))
</code>```

and after testing with leading zeros, came back everytime with the correct representation.

hope this helps.

OwnerDisplayName: rball

Body:
I have a simple html block like:

8

Using jquery I'm trying to add a 1 to the value (8).

var currentValue = $("#replies").text();
var newValue = currentValue + 1;
$("replies").text(newValue);

What's happening is it is appearing like:

81

then

811

not 9, which would be the correct answer.  What am I doing wrong?

Body:
In regards to the octal misinterpretation of .js - I just used this...

parseInt(parseFloat(nv))

and after testing with leading zeros, came back everytime with the correct representation.

hope this helps.


问:
android nfc read and write at the same time/one contact
I'm trying to read data from an NFC tag and then save the data back to the NFC tag.
Is it necessary to connect the NFC tag to the smartphone for each access (read / write) and then remove it again, or is it possible to leave the NFC tag on the mobile phone while the data is being read out and then stored again on it.

Thanks :)

答:
UPDATE:
Since I was down voted, I realized I did not read your question fully. You are dealing with tags and not Beam NFC P2P, so allow me to update my answer to include Tag back and forths.

First you tap and get your tag from your manifest filtered tag types.
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
Ndef ndefTag = Ndef.get(tag);

Then you can then connect() and
writeNdefMessage(…)

There is no need to pull away and tap again.

Also here are some helpful tools if you don't want to write the bloat. https://github.com/skjolber/ndef-tools-for-android

Old Answer: (leaving in case it helps someone in the P2P NFC space)
This was based on P2P beam NFC technology if you are communicating with an NFC device like Google Pay for example where you can do many back and forth as long as you are near. Take Google Payment NFC for example, it reads the info from your device, then does a handshake back and forth via NFC and then performs the transaction. I actually wrote a software that did this exact thing for Gift Card processing and secure encryption handshake back and forth.

It requires a little extra work in your coding, but you can definitely do it.

https://developer.android.com/guide/topics/connectivity/nfc/hce.html

see this topic for details. It is not quite the same as a quick read or write, but you can definitely go back and forth no problem.


问:
Are there tools to repair OPUS file stream?
Opus audio codec format [and OGG as its container] started to gain traction, which is great. However it also means that everyday problems surface. Mine today is a corrupted file, and the question is whether there are tools to repair the stream.

The actual stream is possibly created by a broken encoder, namely:

```<code>  Encoded with Gagravarr.org Java Vorbis Tools v0.8 20160217
</code>```

and opusinfo correctly complains:

```<code>**WARNING: Invalid header page in stream 1, contains multiple packets**
New logical stream (#1, serial: 000052c9): type opus
**WARNING: Implausibly low preskip in Opus stream (1)**
Encoded with Gagravarr.org Java Vorbis Tools v0.8 20160217
Opus stream 1:
        Pre-skip: 0
        Playback gain: 0 dB
        Channels: 1
        Original sample rate: 16000Hz
        Packet duration:   60.0ms (max),   60.0ms (avg),   60.0ms (min)
        Page duration:     60.0ms (max),   60.0ms (avg),   60.0ms (min)
        Total data length: 12231171 bytes (overhead: 13.9%)
        Playback length: 60m:49.920s
        Average bitrate: 26.81 kb/s, w/o overhead: 23.08 kb/s
Logical stream 1 ended
</code>```

which is fine. But while the data is visibly there, opusdec decides to force correctness:

```<code>Decoding to 48000 Hz (1 channel)
Extra packets on initial header page. Invalid stream.
</code>```

and absolutely reject to process the file, which isn't very helpful.

My question is: how the user is supposed to salvage/repair/fix a broken, but salvageable file? Is there a (FOSS) code for that? Is there some hidden functionality in xiph stuff?

答:
Please report the warnings and error to encoder's upstream. The point of opusinfo and opusdec complaining to get people to fix their software and stop making broken files. In addition to the extra packets and unset pre-skip value, 60 ms packet durations probably aren't what you want.

There's no fixup program in xiph's opus-tools package. You could try remuxing it with something like ffmpeg in.opus -acodec copy out.opus which might correct the incorrect paging. There's no good way to correct the missing pre-skip value.

Body:
Opus audio codec format [and OGG as its container] started to gain traction, which is great. However it also means that everyday problems surface. Mine today is a corrupted file, and the question is whether there are tools to repair the stream.

The actual stream is possibly created by a broken encoder, namely:

  Encoded with Gagravarr.org Java Vorbis Tools v0.8 20160217

and opusinfo correctly complains:

**WARNING: Invalid header page in stream 1, contains multiple packets**
New logical stream (#1, serial: 000052c9): type opus
**WARNING: Implausibly low preskip in Opus stream (1)**
Encoded with Gagravarr.org Java Vorbis Tools v0.8 20160217
Opus stream 1:
        Pre-skip: 0
        Playback gain: 0 dB
        Channels: 1
        Original sample rate: 16000Hz
        Packet duration:   60.0ms (max),   60.0ms (avg),   60.0ms (min)
        Page duration:     60.0ms (max),   60.0ms (avg),   60.0ms (min)
        Total data length: 12231171 bytes (overhead: 13.9%)
        Playback length: 60m:49.920s
        Average bitrate: 26.81 kb/s, w/o overhead: 23.08 kb/s
Logical stream 1 ended

which is fine. But while the data is visibly there, opusdec decides to force correctness:

Decoding to 48000 Hz (1 channel)
Extra packets on initial header page. Invalid stream.

and absolutely reject to process the file, which isn't very helpful.

My question is: how the user is supposed to salvage/repair/fix a broken, but salvageable file? Is there a (FOSS) code for that? Is there some hidden functionality in xiph stuff?