2014-09-13 4 views
0

GAE : PHP 런타임에 응용 프로그램이 있으며 Google Cloud Datastore API를 사용하여 PHP 응용 프로그램에서 Datastore에 연결합니다.클라우드 Datastore API - php - GqlQuery - "SELECT * FROM kind_name WHERE __key__"

내 질문 :

가 어떻게 키를 사용하여 내 데이터베이스, SQL에서 "SELECT * FROM table_name WHERE id <= 1410611039" 비슷한을 조회 할 수 있습니다.

내 코드 : (나는 사람들이이 쿼리 문자열 구문을 사용하는 본 적이과 그들을 위해 작동)

$gql_query = new Google_Service_Datastore_GqlQuery(); 
$gql_query->setQueryString("SELECT * FROM notification WHERE __key__ = KEY('notification', 1410611039)"); 

내가 오류의 일부가 Fatal error: Uncaught exception ... (400) Disallowed literal: KEY...

내 데이터 저장소 콘솔입니다 보기 : enter image description here

WHERE __key__ = KEY('notification', 1410611039)을 query_string에 붙일 때까지는 문제가 없습니다.

+0

Cloud Datastore GQL은 App Engine GQL과 약간 다릅니다. 나는 정확한 문제에 대해서는 잘 모르겠다. 따옴표없이'notification'을 시도해 보셨습니까? –

+0

예, 그냥 따옴표없이'notification'을 시도했지만 여전히 같은 오류입니다. 아쉽게도 Datastore API에는 Gql 문자열을 만드는 방법에 대한 가이드가 없습니다. KEY ('kind', 'name/id')는 Datastore 키를 만드는 방법이지만 API를 통해 작동하지 않습니다. –

답변

2

키는 Cloud Datastore GQL의 리터럴로 간주되며 특별한 처리가 필요합니다.

사용자가 런타임에 값을 제공하는 경우 인수 바인딩을 사용하는 것이 좋습니다. 이렇게하면 주입 공격과 같은 악의적 인 동작을 방지하는 데 도움이됩니다.

이렇게하는 데는 두 가지 방법이 있습니다. 두 키 값으로 시작 아니오

는 는
$key_path_element = new Google_Service_Datastore_KeyPathElement(); 
$key_path_element->setKind('notification'); 
$key_path_element->setId(1410611039); 

$key = new Google_Service_Datastore_Key(); 
$key.setPath([$key_path_element]); 

$key_value = new Google_Service_Datastore_Value(); 
$key_value->setKeyValue($key); 
는 는

$key_value 후 사용할 수 중 하나라는 인수 :로

$gql_query = new Google_Service_Datastore_GqlQuery(); 
$gql_query->setQueryString("SELECT * FROM notification WHERE __key__ = $theKey"); 

$name_arg = new Google_Service_Datastore_GqlQueryArg(); 
$name_arg->setName("theKey"); 
$name_arg->setValue($key_value); 

$gql_query->setNameArgs([$name_arg]); 

또는 위치 인수

:

$gql_query = new Google_Service_Datastore_GqlQuery(); 
$gql_query->setQueryString("SELECT * FROM notification WHERE __key__ = @1"); 

$number_arg = new Google_Service_Datastore_GqlQueryArg(); 
$number_arg->setValue($key_value); 

$gql_query->setNumberArgs([$number_arg]); 

에는 사용자가 제공 한 경우 입력이 쿼리에 추가되는 경우 다른 옵션은 요청에서 리터럴을 명시 적으로 허용하는 것입니다.

$gql_query = new Google_Service_Datastore_GqlQuery(); 
$gql_query->setQueryString("SELECT * FROM notification WHERE __key__ = KEY('notification', 1410611039)"); 
$gql_query->setAllowLiteral(true); 

여기에 argument binding에 대한 몇 가지 추가 세부 정보가 있으며 여기에 full GQL reference이 있습니다.

+0

깨끗한 설명을 해 주셔서 감사합니다. 그래서,'$ gql_query-> setAllowLiteral (true);'가 빠졌습니다. 내 문제는 "키가 리터럴로 간주됩니다"라는 사실을 알지 못했고 솔직히 말해서 나는 영어 수준으로 인해 그것이 무엇을 의미하는지 아직도 알지 못한다! 누군가가 내게 단서를 줄 수 있다면 좋을 것입니다. –

0

Java Datastore API를 사용하여 동일한 문제가 발생했습니다. Java의 솔루션은 다음과 같습니다.

datastore = DatastoreOptions.builder() 
.authCredentials(AuthCredentials.createApplicationDefaults()) 
.build() 
.service(); 
String id = "asdf123"; 
Query<Entity> query = Query.gqlQueryBuilder(
    Query.ResultType.ENTITY, 
    "SELECT * FROM Task WHERE id = '"+id+"'") 
    .allowLiteral(true) 
    .build(); 
QueryResults<Entity> result = datastore.run(query); 
while(result.hasNext()){ 
    Entity temp = result.next(); 
    //(...) 
}