Fixture_.java
/*
** Module : Fixture_.java
** Abstract : Implementation of the OEUnit.Data.Fixture class.
**
** Copyright (c) 2023-2025, Golden Code Development Corporation.
**
** -#- -I- --Date-- -------------------------------Description--------------------------------
** 001 VVT 20230318 Created initial version
** 002 CA 20231113 The 'execute' method must be annotated with LegacySignature Type.Execute, and also can be
** dropped if is a no-op.
** 003 CA 20250317 Added 'fixtures' variable.
*/
/*
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero General Public License as
** published by the Free Software Foundation, either version 3 of the
** License, or (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Affero General Public License for more details.
**
** You may find a copy of the GNU Affero GPL version 3 at the following
** location: https://www.gnu.org/licenses/agpl-3.0.en.html
**
** Additional terms under GNU Affero GPL version 3 section 7:
**
** Under Section 7 of the GNU Affero GPL version 3, the following additional
** terms apply to the works covered under the License. These additional terms
** are non-permissive additional terms allowed under Section 7 of the GNU
** Affero GPL version 3 and may not be removed by you.
**
** 0. Attribution Requirement.
**
** You must preserve all legal notices or author attributions in the covered
** work or Appropriate Legal Notices displayed by works containing the covered
** work. You may not remove from the covered work any author or developer
** credit already included within the covered work.
**
** 1. No License To Use Trademarks.
**
** This license does not grant any license or rights to use the trademarks
** Golden Code, FWD, any Golden Code or FWD logo, or any other trademarks
** of Golden Code Development Corporation. You are not authorized to use the
** name Golden Code, FWD, or the names of any author or contributor, for
** publicity purposes without written authorization.
**
** 2. No Misrepresentation of Affiliation.
**
** You may not represent yourself as Golden Code Development Corporation or FWD.
**
** You may not represent yourself for publicity purposes as associated with
** Golden Code Development Corporation, FWD, or any author or contributor to
** the covered work, without written authorization.
**
** 3. No Misrepresentation of Source or Origin.
**
** You may not represent the covered work as solely your work. All modified
** versions of the covered work must be marked in a reasonable way to make it
** clear that the modified work is not originating from Golden Code Development
** Corporation or FWD. All modified versions must contain the notices of
** attribution required in this license.
*/
package com.goldencode.p2j.oo.oeunit.data;
import static com.goldencode.p2j.report.ReportConstants.*;
import static com.goldencode.p2j.util.BlockManager.*;
import java.util.*;
import java.util.function.*;
import com.goldencode.p2j.oo.lang.*;
import com.goldencode.p2j.persist.*;
import com.goldencode.p2j.persist.lock.*;
import com.goldencode.p2j.util.*;
import com.goldencode.p2j.util.InternalEntry.*;
/**
* Implementation for OEUnit.Data.Fixture.
*/
@LegacyResource(resource = "OEUnit.Data.Fixture")
@LegacyResourceSupport(supportLvl = CVT_LVL_FULL | RT_LVL_FULL)
public class Fixture_
extends BaseObject
{
@LegacySignature(type = Type.VARIABLE, name = "Fixtures")
protected object<? extends com.goldencode.p2j.oo.oeunit.util.List> fixtures = TypeFactory.object(com.goldencode.p2j.oo.oeunit.util.List.class);
/**
* The list of datasets
*/
protected final List<DataSet> datasets = new ArrayList<>();
/**
* The static constructor
*/
@LegacySignature(type = Type.CONSTRUCTOR)
public static void __oeunit_data_Fixture__constructor__static__()
{
externalProcedure(Fixture_.class, new Block((Body) () -> {
onRoutineLevel(Condition.ERROR, Action.THROW);
}));
}
/**
* The constructor
*/
@LegacySignature(type = Type.CONSTRUCTOR)
public void __oeunit_data_Fixture__constructor__()
{
internalProcedure(Fixture_.class, this, "__oeunit_data_fixture__constructor__",
new Block((Body) () -> {
__lang_BaseObject_constructor__();
}));
}
/**
* The destructor
*/
@LegacySignature(type = Type.DESTRUCTOR)
public void __oeunit_data_Fixture__destructor__()
{
internalProcedure(Fixture_.class, this, "__oeunit_data_Fixture__destructor__",
new Block((Body) () -> {
for(final DataSet ds : datasets)
{
ds.delete();
}}));
}
/**
* The 'execute' method
*/
@LegacySignature(type = Type.EXECUTE)
public void __oeunit_data_Fixture__execute__()
{
onRoutineLevel(Condition.ERROR, Action.THROW);
}
/**
* Create data in the attached databases, based on data in dataset tables.
*
* @return {@code true} if the operation succeeded, {@code false} if there is no
* datasets in this fixture or any error occurred while creating data from the datasets.
*/
public final boolean createData()
{
if (datasets.isEmpty())
{
return false;
}
for (final DataSet dsData : datasets)
{
final int numTopBuffers = dsData._getNumTopBuffers();
for (int i = 0; i < numTopBuffers; i++)
{
// Note: counters are 1-based in OE
final handle hBuffer = dsData.getTopBuffer(i + 1);
if (!hBuffer._isValid())
{
return false;
}
// HandleOps.delete(hQbuffer);
final handle hQuerybuffer = TypeFactory.handle();
RecordBuffer.create(hQuerybuffer, hBuffer);
final character name = hBuffer.unwrap().name();
final handle hDestbuffer = TypeFactory.handle();
RecordBuffer.create(hDestbuffer, name);
final handle hQuery = TypeFactory.handle();
QueryWrapper.createQuery(hQuery);
final P2JQuery query = hQuery.unwrapQuery();
try
{
if (!query.setBuffers(hQuerybuffer).booleanValue()
|| !query.prepare("FOR EACH " + name.toStringMessage() + " NO-LOCK:").booleanValue()
|| !query.queryOpen().booleanValue())
{
return false;
}
if (query.getFirst(LockType.LT_NONE).booleanValue())
{
final Buffer destBuffer = hDestbuffer.unwrapBuffer();
while (!query.isOffEnd().booleanValue())
{
destBuffer.bufferCreate();
destBuffer.bufferCopy(hQuerybuffer);
destBuffer.bufferRelease();
query.getNext();
}
}
query.queryClose();
}
finally
{
HandleOps.delete(hDestbuffer);
HandleOps.delete(hQuerybuffer);
HandleOps.delete(hQuery);
}
}
}
return true;
}
/**
* Initialize this fixture from a dataset.
*
* @param _dsSrc
* the source dataset handle
*
* @return {@code true} if the operation succeeded
*/
@LegacySignature(type = Type.METHOD, name = "FromDataSet", returns = "LOGICAL", parameters = {
@LegacyParameter(name = "dsSrc", type = "HANDLE", mode = "INPUT") })
public logical fromDataSet(final handle _dsSrc)
{
final handle dsSrc = TypeFactory.initInput(_dsSrc);
return addDataset("FromDataSet", ds -> {
return ds.copyDataset(dsSrc).booleanValue() ? ds : null;
});
}
/**
* Initialize from a JSON code.
*
* @param json
* the JSON code
*
* @return {@code true} if the operation succeeded
*/
@SuppressWarnings("resource")
@LegacySignature(type = Type.METHOD, name = "FromJSON", returns = "LOGICAL", parameters = {
@LegacyParameter(name = "json", type = "LONGCHAR", mode = "INPUT") })
public logical fromJson(final Text json)
{
return addDataset("FromJSON", ds -> {
return ds.readJson(new SourceData("LONGCHAR", json),
new character("EMPTY")).booleanValue() ? ds : null;
});
}
/**
* Initialize from a JSON file.
*
* @param path
* the JSON file
*
* @return {@code true} if the operation succeeded
*/
@SuppressWarnings("resource")
@LegacySignature(type = Type.METHOD, name = "FromJSONFile", returns = "LOGICAL", parameters = {
@LegacyParameter(name = "path", type = "CHARACTER", mode = "INPUT") })
public logical fromJsonfile(final Text path)
{
return addDataset("FromJSONFile", ds -> {
return ds.readJson(new SourceData("FILE", path),
new character("EMPTY")).booleanValue() ? ds : null;
});
}
/**
* Initialize from a TEMP-TABLE.
*
* @param _ttSrc
* the source TEMP-TABLE handle
*
* @return {@code true} if the operation succeeded
*/
@LegacySignature(type = Type.METHOD, name = "FromTempTable", returns = "LOGICAL", parameters = {
@LegacyParameter(name = "ttSrc", type = "HANDLE", mode = "INPUT") })
public logical fromTempTable(final handle _ttSrc)
{
final handle ttSrc = TypeFactory.initInput(_ttSrc);
return addDataset("FromTempTable",
ds -> {
final handle ttData = TypeFactory.handle();
TempTableBuilder.create(ttData);
final logical res = ttData.unwrapTempTableDuplicator().copyTempTable(ttSrc,
new logical(false), new logical(false), new logical(false),
new character(""));
if (!res.booleanValue())
{
HandleOps.delete(ttData);
return null;
}
final handle ttDataBuf = ttData.unwrapTempTable().defaultBufferHandle();
ds.addBuffer(ttDataBuf);
return ds;
});
}
/**
* Initialize from XML code.
*
* @param xml
* source XML text
*
* @return {@code true} if the operation succeeded
*/
@LegacySignature(type = Type.METHOD, name = "FromXML", returns = "LOGICAL", parameters = {
@LegacyParameter(name = "xml", type = "LONGCHAR", mode = "INPUT") })
public logical fromXml(final longchar xml)
{
return addDataset("FromXML", ds -> {
return ds.readXml(new SourceData("LONGCHAR", xml),
new character("EMPTY"), new character(), new logical()).booleanValue() ? ds : null;
});
}
/**
* Initialize from an XML file.
*
* @param path
* the XML file
*
* @return {@code true} if the operation succeeded
*/
@LegacySignature(type = Type.METHOD, name = "FromXMLFile", returns = "LOGICAL", parameters = {
@LegacyParameter(name = "path", type = "CHARACTER", mode = "INPUT") })
public logical fromXmlfile(final character path)
{
return addDataset("FromXMLFile", ds -> {
return ds.readXml(new SourceData("FILE", path),
new character("EMPTY"), new character(), new logical()).booleanValue() ? ds : null;
});
}
/**
* Get number of datasets in this fixture
*
* @return see above
*/
@LegacySignature(type = Type.GETTER, name = "Size", returns = "INTEGER")
public integer getSize()
{
return function(Fixture_.class, this, "Size", integer.class, new Block((Body) () -> {
storeReturnValue(datasets.size());
}));
}
/**
* Get total number of tables in all datasets
*
* @return see above
*/
@LegacySignature(type = Type.GETTER, name = "TableCount", returns = "INTEGER")
public integer getTableCount()
{
return function(Fixture_.class, this, "TableCount", integer.class, new Block((Body) () -> {
int result = 0;
for (final DataSet ds : datasets)
{
result += ds != null ? ds.getNumTopBuffers().intValue() : 0;
}
storeReturnValue(result);
}));
}
/**
* Create, initialize and add a fixture dataset.
*
* @param method
* the legacy method name
* @param initialize
* function to initialize dataset, on success returns the dataset, or error
* returns {@code null}
*
* @return {@code true} on success
*/
private logical addDataset(final String method, final Function<DataSet, DataSet> initialize)
{
return function(Fixture_.class, this, method, logical.class, new Block((Body) () -> {
final handle h = new handle();
DataSet.create(h);
final DataSet ds = (DataSet) h.getResource();
assert ds != null;
if (initialize.apply(ds) != null)
{
datasets.add(ds);
storeReturnValue(true);
}
else
{
ds.delete();
storeReturnValue(false);
}
}));
}
}