recycleView is not showing data from sqlite database - android-studio

{
Cursor cursor = db.readAllItems();//this read data from sqlite and save the data in cursor
if (cursor.getCount() == 0){`it confire the data
Toast.makeText(this, "NO data in it",Toast.LENGTH_SHORT).show();
}else {
while (cursor.moveToNext()){
id.add(cursor.getInt(0));
iname.add(cursor.getString(2));
qty.add(cursor.getInt(3));
}
}
db.close();
cursor.close();
}

Related

How to iterate and update records?

I describe what I'm trying to do in VBA because it's the language I know best :
'Declare a recordset which will iterate through our records
Dim rs as DAO.recordset
'Setup a connection to our data store with the table/query we want to process records in
Set rs = dbengine.workspaces.opendatabase('path/to/database').openrecordset('select * from sometable')
rs.movefirst
Do Until rs.eof
'put record in edit mode
rs.Edit
rs!field = 'some value I want'
'put record in update mode
rs.update
rs.movenext
loop
It's looping and setting values. What I need is more complex (updating based on what is in the next row after and all of that), but I can figure that out myself once I understand how to iterate through records and perform updates at record level.
What I have now:
//this function is just is called by another function. processRecord is what does the individual record processing
async function processRecords(db: Database, SQL: string, processRecord: any) {
db.each(SQL, async(e,r) => {
if(e) {
reject(e);
} else {
try {
await processRecord(db,r);
resolve(true);
}
catch(e) {
reject(e);
}
}
});
}
async function processRecord(db: Database, r: Row) {
try {
//execute a query against the current row we are processing
//SQL for updates uses a select in SET clause to pull data from the record with the next rowid
//executeQuery is a "promisified" db.run
executeQuery(db,updateSQL,r.rowID);
} catch(e : any) {
throw e;
}
}
//I borrowed this from somewhere else and modified it a bit.
function executeQuery(db: Database, SQL: string, params: any = []) : Promise<number> {
return new Promise(resolve,reject) => {
db.Run(SQL,params,function(e) {
if(e) {
reject(e);
} else {
resolve(this.changes);
}
}
}
}
How to iterate through records and perform updates at record level?

What is the new button name for Base.Actions["LSPOReceiptLine_binLotSerial"].Press()?

I have inherited an older customization to the Purchase Receipts / PO302000 screen that I'm trying to upgrade, and it had customization code to import Lot/Serial nbrs from an Excel spreadsheet. It all seems to work alright, except that at the end, it errors out when pressing a button as follows:
Base.Actions["LSPOReceiptLine_binLotSerial"].Press();
Here's the entire code:
public virtual void importAllocations()
{
try
{
if (Base.transactions.Current != null)
{
var siteid = Base.transactions.Current.SiteID;
if (Base.splits.Select().Count == 0)
{
if (this.NewRevisionPanel.AskExt() == WebDialogResult.OK)
{
const string PanelSessionKey = "ImportStatementProtoFile";
PX.SM.FileInfo info = PX.Common.PXContext.SessionTyped<PXSessionStatePXData>().FileInfo[PanelSessionKey] as PX.SM.FileInfo;
System.Web.HttpContext.Current.Session.Remove(PanelSessionKey);
if (info != null)
{
byte[] filedata = info.BinData;
using (NVExcelReader reader = new NVExcelReader())
{
Dictionary<UInt32, string[]> data = reader.loadWorksheet(filedata);
foreach (string[] textArray in data.Values)
{
if (textArray[0] != GetInventoryCD(Base.transactions.Current.InventoryID))
{
throw (new Exception("InventoryID in file does not match row Inventory ID"));
}
else
{
//Find the location ID based on the location CD provided by the Excel sheet...
INLocation inloc = PXSelect<INLocation,
Where<INLocation.locationCD, Equal<Required<INLocation.locationCD>>,
And<INLocation.siteID, Equal<Required<INLocation.siteID>>>>>.Select(Base
, textArray[1]
, Base.transactions.Current.SiteID);
Base.splits.Insert(new POReceiptLineSplit()
{
InventoryID = Base.transactions.Current.InventoryID,
LocationID = inloc.LocationID, //Convert.ToInt32(textArray[1]), //Base.transactions.Current.LocationID,
LotSerialNbr = textArray[2],
Qty = Decimal.Parse(textArray[3])
});
}
}
}
}
}
}
}
Base.Actions["LSPOReceiptLine_binLotSerial"].Press();
}
catch (FileFormatException fileFormat)
{
// Acuminator disable once PX1053 ConcatenationPriorLocalization [Justification]
throw new PXException(String.Format("Incorrect file format. File must be of type .xlsx", fileFormat.Message));
}
catch (Exception ex)
{
throw ex;
}
}
Now, there seems to be no such button - and I have no idea what it would be called now, or if it even still exists. I don't even really know what this action did.
Any ideas?
Thanks much...
That logic has been moved into the PX.Objects.PO.GraphExtensions.POReceiptEntryExt.POReceiptLineSplittingExtension. That action was doing the following in the PX.Objects.PO.LSPOReceiptLine
// PX.Objects.PO.LSPOReceiptLine
// Token: 0x0600446F RID: 17519 RVA: 0x000EE86C File Offset: 0x000ECA6C
public override IEnumerable BinLotSerial(PXAdapter adapter)
{
if (base.MasterCache.Current != null)
{
if (!this.IsLSEntryEnabled((POReceiptLine)base.MasterCache.Current))
{
throw new PXSetPropertyException("The Line Details dialog box cannot be opened because changing line details is not allowed for the selected item.");
}
this.View.AskExt(true);
}
return adapter.Get();
}
Now it is called ShowSplits and is part of the POReceiptLineSplittingExtension extension.
// PX.Objects.PO.GraphExtensions.POReceiptEntryExt.POReceiptLineSplittingExtension
// Token: 0x06005359 RID: 21337 RVA: 0x00138621 File Offset: 0x00136821
public override IEnumerable ShowSplits(PXAdapter adapter)
{
if (base.LineCurrent == null)
{
return adapter.Get();
}
if (!this.IsLSEntryEnabled(base.LineCurrent))
{
throw new PXSetPropertyException("The Line Details dialog box cannot be opened because changing line details is not allowed for the selected item.");
}
return base.ShowSplits(adapter);
}
Given the fact that ShowSplits is defined in the LineSplittingExtension originally it may be referred to as "LineSplittingExteions_ShowSplits" or "POReceiptLineSplittingExtension_ShowSplits". I would suggest including that POReceiptLineSplittingExtension as part of your extension and simply call the Base1.ShowSplits

File Deleted from MediaStore but not deleted from Storage

I'm creating a Music Player. I know that in Api 29 and above , we should Send Request to User for deleting Music file in MediaStore.
and this is where result get back in Api 29 and above:
intentSenderRequest = registerForActivityResult(new ActivityResultContracts.StartIntentSenderForResult(), new ActivityResultCallback<ActivityResult>() {
#Override
public void onActivityResult(ActivityResult result) {
if (result.getResultCode() == Activity.RESULT_OK) {
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.Q) {
getActivity().getApplication().getContentResolver().delete(deleteUri, null, null);
}
Toast.makeText(getActivity(), deleteAudioModel.getData(), Toast.LENGTH_SHORT).show();
File file = new File(deleteAudioModel.getData());
file.delete();
adapter.itemDeleted(itemForDelete);
} else {
Toast.makeText(getActivity(), "Not Deleted", Toast.LENGTH_SHORT).show();
}
}
});
but the music just delete from MediaStore and remain in device storage.
I tried to delete it after User permission by MediaStore.Audio.Media.DATA and File.delete method,
but I've got no result.
is there any way for delete file in Api 29 and above?

Why Readable.push() return false every time Readable._read() is called

I have the following readable stream in typescript:
import {Readable} from "stream";
enum InputState {
NOT_READABLE,
READABLE,
ENDED
}
export class Aggregator extends Readable {
private inputs: Array<NodeJS.ReadableStream>;
private states: Array<InputState>;
private records: Array<any>;
constructor(options, inputs: Array<NodeJS.ReadableStream>) {
// force object mode
options.objectMode = true;
super(options);
this.inputs = inputs;
// set initial state
this.states = this.inputs.map(() => InputState.NOT_READABLE);
this.records = this.inputs.map(() => null);
// register event handlers for input streams
this.inputs.forEach((input, i) => {
input.on("readable", () => {
console.log("input", i, "readable event fired");
this.states[i] = InputState.READABLE;
if (this._readable) { this.emit("_readable"); }
});
input.on("end", () => {
console.log("input", i, "end event fired");
this.states[i] = InputState.ENDED;
// if (this._end) { this.push(null); return; }
if (this._readable) { this.emit("_readable"); }
});
});
}
get _readable () {
return this.states.every(
state => state === InputState.READABLE ||
state === InputState.ENDED);
}
get _end () {
return this.states.every(state => state === InputState.ENDED);
}
_aggregate () {
console.log("calling _aggregate");
let timestamp = Infinity,
indexes = [];
console.log("initial record state", JSON.stringify(this.records));
this.records.forEach((record, i) => {
// try to read missing records
if (!this.records[i] && this.states[i] !== InputState.ENDED) {
this.records[i] = this.inputs[i].read();
if (!this.records[i]) {
this.states[i] = InputState.NOT_READABLE;
return;
}
}
// update timestamp if a better one is found
if (this.records[i] && timestamp > this.records[i].t) {
timestamp = this.records[i].t;
// clean the indexes array
indexes.length = 0;
}
// include the record index if has the required timestamp
if (this.records[i] && this.records[i].t === timestamp) {
indexes.push(i);
}
});
console.log("final record state", JSON.stringify(this.records), indexes, timestamp);
// end prematurely if after trying to read inputs the aggregator is
// not ready
if (!this._readable) {
console.log("end prematurely trying to read inputs", this.states);
this.push(null);
return;
}
// end prematurely if all inputs are ended and there is no remaining
// record values
if (this._end && indexes.length === 0) {
console.log("end on empty indexes", this.states);
this.push(null);
return;
}
// create the aggregated record
let record = {
t: timestamp,
v: this.records.map(
(r, i) => indexes.indexOf(i) !== -1 ? r.v : null
)
};
console.log("aggregated record", JSON.stringify(record));
if (this.push(record)) {
console.log("record pushed downstream");
// remove records already aggregated and pushed
indexes.forEach(i => { this.records[i] = null; });
this.records.forEach((record, i) => {
// try to read missing records
if (!this.records[i] && this.states[i] !== InputState.ENDED) {
this.records[i] = this.inputs[i].read();
if (!this.records[i]) {
this.states[i] = InputState.NOT_READABLE;
}
}
});
} else {
console.log("record failed to push downstream");
}
}
_read () {
console.log("calling _read", this._readable);
if (this._readable) { this._aggregate(); }
else {
this.once("_readable", this._aggregate.bind(this));
}
}
}
It is designed to aggregate multiple input streams in object mode. In the end it aggregate multiple time series data streams into a single one. The problem i'm facing is that when i test the feature i'm seeing repeatedly the message record failed to push downstream and immediately the message calling _read true and in between just the 3 messages related to the aggregation algorithm. So the Readable stream machinery is calling _read and every time it's failing the push() call. Any idea why is this happening? Did you know of a library that implement this kind of algorithm or a better way to implement this feature?
I will answer myself the question.
The problem was that i was misunderstanding the meaning of the this.push() return value call. I think a false return value mean that the current push operation fail but the real meaning is that the next push operation will fail.
A simple fix to the code shown above is to replace this:
if (this.push(record)) {
console.log("record pushed downstream");
// remove records already aggregated and pushed
indexes.forEach(i => { this.records[i] = null; });
this.records.forEach((record, i) => {
// try to read missing records
if (!this.records[i] && this.states[i] !== InputState.ENDED) {
this.records[i] = this.inputs[i].read();
if (!this.records[i]) {
this.states[i] = InputState.NOT_READABLE;
}
}
});
} else {
console.log("record failed to push downstream");
}
By this:
this.push(record);
console.log("record pushed downstream");
// remove records already aggregated and pushed
indexes.forEach(i => { this.records[i] = null; });
this.records.forEach((record, i) => {
// try to read missing records
if (!this.records[i] && this.states[i] !== InputState.ENDED) {
this.records[i] = this.inputs[i].read();
if (!this.records[i]) {
this.states[i] = InputState.NOT_READABLE;
}
}
});
You can notice that the only difference is avoid conditioning operations on the return value of the this.push() call. Given that the current implementation call this.push() only once per _read() call this simple change solve the issue.
It means feeding is faster than consuming. The official approach is enlarge its highWaterMark, Default: 16384 (16KB), or 16 for objectMode. As long as its inner buffer is big enough, the push function will always return true. It does not have to be single push() in single _read(). You may push as much as the highWaterMark indicates in a single _read().

How can i override set_message multiple time in foreach in codeginiter?

foreach($all_fields as $row){
$datatype = $this->sys_model->get_table_data_by_datatype_id('datatype',$row['datatype_id']);
$msg = $this->sys_model->get_validation_message_by_datatype_id('validation_message',$row['datatype_id']);
if($datatype[0]['datatype'] == 'email'){
$this->form_validation->set_rules($row['field_name'],$row['field_name'], 'required|trim|xss_clean|valid_email');
$this->form_validation->set_message('required',$msg[0]['validation_msg']);
}
elseif($datatype[0]['datatype'] == 'number'){
$this->form_validation->set_rules($row['field_name'],$row['field_name'], 'required|numeric');
$this->form_validation->set_message('required',$msg[0]['validation_msg']);
}else{
$this->form_validation->set_rules($row['field_name'],$row['field_name'], 'required');
$this->form_validation->set_message('required',$msg[0]['validation_msg']);
}
}
i want to set validation message dynamically from backend based on datatype but it takes same message for all fields..
How can i set different message for all fields based on datatype ?
create a callback functions for each datatype
function validate_string($str)
{
if(condition) )
{
return true;
}
else
{
$this->form_validation->set_message('validate_string', 'The %s your custom error message');
return false;
}
}
$this->form_validation->set_rules('field1', 'label1', 'validate_string');
$this->form_validation->set_rules('field2', 'label2', 'validate_string');
$this->form_validation->set_rules('field3', 'label3', 'validate_string');
$this->form_validation->set_rules('field4', 'label4', 'validate_string');

Resources