i have a kmm project which using apollo graphql version 3.3.2
Everything okay with the previous apollo version but the new version i have to set variables with Optional.presentIfNotNull($variable) like this.
val officeId = QueryTrainingsForUserWhereWhereConditions(
Optional.presentIfNotNull(TrainingColumn.OFFICE_ID),
Optional.presentIfNotNull(SQLOperator.IS_NULL)
)
Before when i use apollo v2 it was like this
val officeId = QueryTrainingsForUserWhereWhereConditions(
TrainingColumn.OFFICE_ID,
SQLOperator.IS_NULL
)
i tried to set
generateOptionalOperationVariables.set(false) and try with true
in gradle file but it didn't work
and when i click the QueryTrainingsForUserWhereWhereConditions
apollo generated the code like this
public data class QueryTrainingsForUserWhereWhereConditions(
/**
* The column that is used for the condition.
*/
public val column: Optional<TrainingColumn?> = Optional.Absent,
/**
* The operator that is used for the condition.
*/
public val `operator`: Optional<SQLOperator?> = Optional.Absent,
/**
* The value that is used for the condition.
*/
public val `value`: Optional<Any?> = Optional.Absent,
/**
* A set of conditions that requires all conditions to match.
*/
public val AND: Optional<List<QueryTrainingsForUserWhereWhereConditions>?> = Optional.Absent,
/**
* A set of conditions that requires at least one condition to match.
*/
public val OR: Optional<List<QueryTrainingsForUserWhereWhereConditions>?> = Optional.Absent,
/**
* Check whether a relation exists. Extra conditions or a minimum amount can be applied.
*/
public val HAS: Optional<QueryTrainingsForUserWhereWhereConditionsRelation?> = Optional.Absent,
)
i couldn't remember what was the generated code before with apollo v2.
it's very hard to use this Optional.presentIfNotNull. method in everywhere and i dont want to use this
Is there any solution to fix my problem or any other way to use Optional.presentIfNotNull to handle optional variables ?
Thanks
Related
I'm having a CodeIgniter project with lots of modules and codes residing in it.
Now I would like to create documentation for other new co-workers.
For example
/**
* inline tags demonstration
*
* This class generates bars using the main algorithm, which also
* works heavily with {#link foo()} to rule the world. If I want
* to use the characters "{#link" in a docblock, I just use "{#}link." If
* I want the characters "{#*}" I use "{#}*}"
*
* #author ahobbit
* #copyright middleearth.org XVII
* #version 1.2.3
*/
class bar
{
// beginning of docblock template area
/**##+
* #access private
* #var string
*/
var $_var1 = 'hello';
var $_var2 = 'my';
var $_var3 = 'name';
var $_var4 = 'is';
var $_var5 = 'Bob';
var $_var6 = 'and';
var $_var7 = 'I';
/**
* Two words
*/
var $_var8 = 'like strings';
/**##-*/
var $publicvar = 'Lookee me!';
}
/**
* Makes chocolate bars
*
* There are two aspects to this class.
* {#inheritdoc } In addition, the foo class
* makes the bars chocolate
*/
class foo extends bar
{
/**
* Check if a Sql row exists. (with two values)
*
* This function will check if a selected sql row exists that contains two
* known values.
*
* #param string $tblname Sql Table Name
* #param string $colname Sql Column Name 1
* #param string $value Sql value 1
* #param string $colname2 Sql Column Name 2
* #param string $value2 Sql value 2
* #return boolean returns true if the sql row does exist
*/
function tableHasRow2D($tblname, $colname, $value, $colname2, $value2) {
$row = sqlQuery("SELECT COUNT(*) AS count FROM $tblname WHERE " . "$colname
LIKE '$value' AND $colname2 LIKE '$value2'");
return $row['count'] ? true : false;
}
}
I had made use of with the following commands
I. PHPdoc
E:\xampp\htdocs\CI_Proj> php phpDocumentor.phar -d application
PHP Warning: count(): Parameter must be an array or an object that implements Countable in phar://E:/xampp/htdocs/CI_Proj/phpDocumentor.phar/vendor/twig/twig/lib/Twig/Extension/Core.php on line 1293
Execute transformation using writer "twig"
Execute transformation using writer "twig"
Execute transformation using writer "twig"
Execute transformation using writer "twig"
Execute transformation using writer "twig"
Execute transformation using writer "Graph"
Unable to find the `dot` command of the GraphViz package. Is GraphViz correctly installed and present in your path? 222.041s
Analyze results and write a report to log
.. 0.004s
II. ApiGen
E:\xampp\htdocs\CI_Proj\vendor\bin>apigen generate src "E:\xampp\htdocs\CI_Proj\application" --destination "E:\xampp\htdocs\CI_Proj\docs-apigen" --debug
Fatal error: Cannot use 'Object' as class name as it is reserved in E:\xampp\htdocs\CI_Proj\vendor\latte\latte\src\Latte\Object.php on line 14
ErrorException: Cannot use 'Object' as class name as it is reserved in E:\xampp\htdocs\CI_Proj\vendor\latte\latte\src\Latte\Object.php:14
Stack trace:
#0 [internal function]: Tracy\Debugger::shutdownHandler()
#1 {main}
Unable to log error: Logging directory is not specified.
Is it be possible to add comments to the modules before or after generation of code?
Since I'm looking to add comments to specific modules in the document itself and optionally that would
automatically inserted to the source code, at the right positions.
How should I need to manage the modules and code inside the project and How would I create a browsable HTML-Documentation?
Any other tool that makes generating the documentation directly from your PHP source code, that would be great in advice
In order to upgrade an existing system, I have to import extended tt_news records to tx_news. The problem is, that the extending of the tx_news Model seems not to work proper and of course this, the import neither.
But in Backend I can see and store data in my additional fields.
What I've done so far:
I've extended tx_news Version 3.2.8
My Model:
class News extends \GeorgRinger\News\Domain\Model\News {
/**
* uidForeign.
*
* #var int
*/
protected $uidForeign;
/**
* Sets the uidForeign.
*
* #param int $uidForeign
*
* #return void
*/
public function setUidForeign($uidForeign)
{
$this->uidForeign = $uidForeign;
}
/**
* Returns the uidForeign.
*
* #return int $uidForeign
*/
public function getUidForeign()
{
return $this->uidForeign;
}
/**
* tableForeign.
*
* #var string
*/
protected $tableForeign;
/**
* Sets the tableForeign.
*
* #param string $tableForeign
*
* #return void
*/
public function setTableForeign($tableForeign)
{
$this->tableForeign = $tableForeign;
}
/**
* Returns the tableForeign.
*
* #return string $tableForeign
*/
public function getTableForeign()
{
return $this->tableForeign;
}
}
ext_localconf:
$GLOBALS['TYPO3_CONF_VARS']['EXT']['news']['classes']['Domain/Model/News'][] = 'news_extend';
I think that should work. The generated class in typo3temp seems correct. My fields including their getter/setter are in there.
But in Controller and FE I can not access these fields.
What am I missing? What else can I check?
If you upgrade a project, I don't know really the reason why you are using an old version of EXT:news.
What could be missing is the TCA definition of the field.
If you want to migrate from tt_news to news, there is a ready-to-use solution which can be found here https://github.com/ext-news/news_ttnewsimport
The reason was an configuration setting for the backend cache.
they have bees set to TYPO3\CMS\Core\Cache\Backend\NullBackend:class instead TYPO3\CMS\Core\Cache\Backend\NullBackend.
Now it works.
I have an api rest and i try to give an optional paramter in my route like this :
/**
* #Rest\View
* #Rest\Get("/dossier/{idDossier}", requirements={"idDossier" = "\d+"}, defaults={"idDossier" = null})
* #ApiDoc(
* description="...",
* parameters={
* {"name"="idDossier", "dataType"="integer", "required"=false, "description"="Folder Id"}
* }
* )
*/
public function getDossierAction($idDossier = null, Request $request){
But i have an error :
[Semantical Error] The annotation "#Rest\View" in method ...\Controller\DossierAPIController::getDossierAction() was never imported. Did you maybe forget to add a "use" statement for this annotation?
Your are not importing that annotation class. Put something like this after the namespace declaration:
use FOS\RestBundle\Controller\Annotations as Rest;
so you can use it like what you have:
#Rest\View()
We’re trying to decide between providing generic vs specific record formats for consumption by our clients
with an eye to providing an online schema registry clients can access when the schemas are updated.
We expect to send out serialized blobs prefixed with a few bytes denoting the version number so schema
retrieval from our registry can be automated.
Now, we’ve come across code examples illustrating the relative adaptability of the generic format for
schema changes but we’re reluctant to give up the type safety and ease-of-use provided by the specific
format.
Is there a way to obtain the best of both worlds? I.e. could we work with and manipulate the specific generated
classes internally and then have them converted them to generic records automatically just before serialization?
Clients would then deserialize the generic records (after looking up the schema).
Also, could clients convert these generic records they received to specific ones at a later time? Some small code examples would be helpful!
Or are we looking at this all the wrong way?
What you are looking for is Confluent Schema registry service and libs which helps to integrate with this.
Providing a sample to write Serialize De-serialize avro data with a evolving schema. Please note providing sample from Kafka.
import io.confluent.kafka.serializers.KafkaAvroDeserializer;
import io.confluent.kafka.serializers.KafkaAvroSerializer;
import org.apache.avro.generic.GenericRecord;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import java.util.HashMap; import java.util.Map;
public class ConfluentSchemaService {
public static final String TOPIC = "DUMMYTOPIC";
private KafkaAvroSerializer avroSerializer;
private KafkaAvroDeserializer avroDeserializer;
public ConfluentSchemaService(String conFluentSchemaRigistryURL) {
//PropertiesMap
Map<String, String> propMap = new HashMap<>();
propMap.put("schema.registry.url", conFluentSchemaRigistryURL);
// Output afterDeserialize should be a specific Record and not Generic Record
propMap.put("specific.avro.reader", "true");
avroSerializer = new KafkaAvroSerializer();
avroSerializer.configure(propMap, true);
avroDeserializer = new KafkaAvroDeserializer();
avroDeserializer.configure(propMap, true);
}
public String hexBytesToString(byte[] inputBytes) {
return Hex.encodeHexString(inputBytes);
}
public byte[] hexStringToBytes(String hexEncodedString) throws DecoderException {
return Hex.decodeHex(hexEncodedString.toCharArray());
}
public byte[] serializeAvroPOJOToBytes(GenericRecord avroRecord) {
return avroSerializer.serialize(TOPIC, avroRecord);
}
public Object deserializeBytesToAvroPOJO(byte[] avroBytearray) {
return avroDeserializer.deserialize(TOPIC, avroBytearray);
} }
Following classes have all the code you are looking for.
io.confluent.kafka.serializers.KafkaAvroDeserializer;
io.confluent.kafka.serializers.KafkaAvroSerializer;
Please follow the link for more details :
http://bytepadding.com/big-data/spark/avro/avro-serialization-de-serialization-using-confluent-schema-registry/
Can I convert between them?
I wrote the following kotlin code to convert from a SpecificRecord to GenericRecord and back - via JSON.
PositionReport is an object generated off of avro with the avro plugin for gradle - it is:
#org.apache.avro.specific.AvroGenerated
public class PositionReport extends org.apache.avro.specific.SpecificRecordBase implements org.apache.avro.specific.SpecificRecord {
...
The functions used are below
/**
* Encodes a record in AVRO Compatible JSON, meaning union types
* are wrapped. For prettier JSON just use the Object Mapper
* #param pos PositionReport
* #return String
*/
private fun PositionReport.toAvroJson() : String {
val writer = SpecificDatumWriter(PositionReport::class.java)
val baos = ByteArrayOutputStream()
val jsonEncoder = EncoderFactory.get().jsonEncoder(this.schema, baos)
writer.write(this, jsonEncoder)
jsonEncoder.flush()
return baos.toString("UTF-8")
}
/**
* Converts from Genreic Record into JSON - Seems smarter, however,
* to unify this function and the one above but whatevs
* #param record GenericRecord
* #param schema Schema
*/
private fun GenericRecord.toAvroJson(): String {
val writer = GenericDatumWriter<Any>(this.schema)
val baos = ByteArrayOutputStream()
val jsonEncoder = EncoderFactory.get().jsonEncoder(this.schema, baos)
writer.write(this, jsonEncoder)
jsonEncoder.flush()
return baos.toString("UTF-8")
}
/**
* Takes a Generic Record of a position report and hopefully turns
* it into a position report... maybe it will work
* #param gen GenericRecord
* #return PositionReport
*/
private fun toPosition(gen: GenericRecord) : PositionReport {
if (gen.schema != PositionReport.getClassSchema()) {
throw Exception("Cannot convert GenericRecord to PositionReport as the Schemas do not match")
}
// We will convert into JSON - and use that to then convert back to the SpecificRecord
// Probalby there is a better way
val json = gen.toAvroJson()
val reader: DatumReader<PositionReport> = SpecificDatumReader(PositionReport::class.java)
val decoder: Decoder = DecoderFactory.get().jsonDecoder(PositionReport.getClassSchema(), json)
val pos = reader.read(null, decoder)
return pos
}
/**
* Converts a Specific Record to a Generic Record (I think)
* #param pos PositionReport
* #return GenericData.Record
*/
private fun toGenericRecord(pos: PositionReport): GenericData.Record {
val json = pos.toAvroJson()
val reader : DatumReader<GenericData.Record> = GenericDatumReader(pos.schema)
val decoder: Decoder = DecoderFactory.get().jsonDecoder(pos.schema, json)
val datum = reader.read(null, decoder)
return datum
}
There are a couple difference however between the two:
Fields in the SpecificRecord that are of Instant type will be encoded in the GenericRecord as long and Enums are slightly different
So for example in my unit test of this function time fields are tested like this:
val gen = toGenericRecord(basePosition)
assertEquals(basePosition.getIgtd().toEpochMilli(), gen.get("igtd"))
And enums are validated by string
val gen = toGenericRecord(basePosition)
assertEquals(basePosition.getSource().toString(), gen.get("source").toString())
So to convert between you can do:
val gen = toGenericRecord(basePosition)
val newPos = toPosition(gen)
assertEquals(newPos, basePosition)
I have a database with a few dozen tables. My app deals with just one of those tables. I'd like propel to generate the schema just for that table. Is there a way I can specify the table(s) in build.properties?
A simple extension of Propel (code examples based on Propel-1.6.8) to allow ignore a custom set of tables (configured using a property):
Extend build-propel.xml:
<!-- Ignore Tables Feature -->
<taskdef
name="propel-schema-reverse-ignore"
classname="task.PropelSchemaReverseIgnoreTask" classpathRef="propelclasses"/>
Extend build.xml:
<target name="reverse-ignore" depends="configure">
<phing phingfile="build-propel.xml" target="reverse-ignore"/>
</target>
Extend PropelSchemaReverseTask:
class PropelSchemaReverseIgnoreTask extends PropelSchemaReverseTask {
/**
* Builds the model classes from the database schema.
* #return Database The built-out Database (with all tables, etc.)
*/
protected function buildModel()
{
// ...
// Loads Classname reverse.customParserClass if present
$customParserClassname = $config->getBuildProperty("reverseCustomParserClass");
if ($customParserClassname!=null) {
$this->log('Using custom parser class: '.$customParserClassname);
$parser = $config->getConfiguredSchemaParserForClassname($con, $customParserClassname);
} else {
$parser = $config->getConfiguredSchemaParser($con);
}
// ...
}
}
Add function to GeneratorConfig:
class GeneratorConfig implements GeneratorConfigInterface {
// ...
/**
* Ignore Tables Feature:
* Load a specific SchemaParser class
*
* #param PDO $con
* #param string $clazzName SchemaParser class to load
* #throws BuildException
* #return Ambigous <SchemaParser, unknown>
*/
public function getConfiguredSchemaParserForClassname(PDO $con = null, $clazzName)
{
$parser = new $clazzName();
if (!$parser instanceof SchemaParser) {
throw new BuildException("Specified platform class ($clazz) does implement SchemaParser interface.", $this->getLocation());
}
$parser->setConnection($con);
$parser->setMigrationTable($this->getBuildProperty('migrationTable'));
$parser->setGeneratorConfig($this);
return $parser;
}
}
Extend MysqlSchemaParser:
class MysqlSchemaIgnoreParser extends MysqlSchemaParser {
public function parse(Database $database, Task $task = null)
{
$this->addVendorInfo = $this->getGeneratorConfig()->getBuildProperty('addVendorInfo');
$stmt = $this->dbh->query("SHOW FULL TABLES");
// First load the tables (important that this happen before filling out details of tables)
$tables = array();
$configIgnoreTables = $this->getGeneratorConfig()->getBuildProperty("reverseIgnoreTables");
$tables_ignore_list = array();
$tables_ignore_list = explode(",", $configIgnoreTables);
if ($task) {
$task->log("Reverse Engineering Tables", Project::MSG_VERBOSE);
}
while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
$name = $row[0];
$type = $row[1];
if (!in_array($name, $tables_ignore_list)) {
// ...
} else {
$task->log("Ignoring table: " .$name);
}
}
// ...
}
}
Add new (optional) properties to build.properties:
# Propel Reverse Custom Properties
propel.reverse.customParserClass=MysqlSchemaIgnoreParser
propel.reverse.ignoreTables = table1,table2
A solution could be to write your own schema parser that ignores certain tables. These tables to exclude could be read from a config file or so.
Take a look at the MysqlSchemaParser.php to get an idea of how such a parser works. You could extend such an existing parser and just override the parse() method. When tables are added, you would check them for exclusion/inclusion and only add them if they meet your subset criteria.
How to create custom propel tasks is described in the Propel cookbook.
Instead of invoking propel-gen reverse you would then invoke your customized reverse engineering task.
If done neatly, I'd find it worth being added as a contribution to the Propel project and you'd definitely deserve fame for that! :-)