Ejemplo n.º 1
0
        /// <summary>
        /// Grants access to a table.
        /// </summary>
        private async Task <IResponse> Grant(IRequestContext request, Route route)
        {
            string tableName = GetAndValidateTableName(route);

            if (!this.Database.TableExists(tableName))
            {
                return(ArribaResponse.NotFound("Table not found to grant permission on."));
            }

            var identity = await request.Request.ReadBodyAsync <SecurityIdentity>();

            if (String.IsNullOrEmpty(identity.Name))
            {
                return(ArribaResponse.BadRequest("Identity name must not be empty"));
            }

            PermissionScope scope;

            if (!Enum.TryParse <PermissionScope>(route["scope"], true, out scope))
            {
                return(ArribaResponse.BadRequest("Unknown permission scope {0}", route["scope"]));
            }

            using (request.Monitor(MonitorEventLevel.Information, "GrantPermission", type: "Table", identity: tableName, detail: new { Scope = scope, Identity = identity }))
            {
                SecurityPermissions security = this.Database.Security(tableName);
                security.Grant(identity.Scope, identity.Name, scope);

                // Save permissions
                this.Database.SaveSecurity(tableName);
            }

            return(ArribaResponse.Ok("Granted"));
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Saves the specified table.
        /// </summary>
        private IResponse Save(IRequestContext request, Route route)
        {
            string tableName = GetAndValidateTableName(route);

            if (!this.Database.TableExists(tableName))
            {
                return(ArribaResponse.NotFound("Table not found to save"));
            }

            using (request.Monitor(MonitorEventLevel.Information, "Save", type: "Table", identity: tableName))
            {
                Table t = this.Database[tableName];

                // Verify before saving; don't save if inconsistent
                ExecutionDetails d = new ExecutionDetails();
                t.VerifyConsistency(VerificationLevel.Normal, d);

                if (d.Succeeded)
                {
                    t.Save();
                    return(ArribaResponse.Ok("Saved"));
                }
                else
                {
                    return(ArribaResponse.Error("Table state inconsistent. Not saving. Restart server to reload. Errors: " + d.Errors));
                }
            }
        }
Ejemplo n.º 3
0
        private IResponse GetAllBasics(IRequestContext ctx, Route route)
        {
            bool hasTables = false;

            Dictionary <string, TableInformation> allBasics = new Dictionary <string, TableInformation>();

            foreach (string tableName in this.Database.TableNames)
            {
                hasTables = true;

                if (HasTableAccess(tableName, ctx.Request.User, PermissionScope.Reader))
                {
                    allBasics[tableName] = GetTableBasics(tableName, ctx);
                }
            }

            // If you didn't have access to any tables, return a distinct result to show Access Denied in the browser
            // but not a 401, because that is eaten by CORS.
            if (allBasics.Count == 0 && hasTables)
            {
                return(ArribaResponse.Ok(null));
            }

            return(ArribaResponse.Ok(allBasics));
        }
        private async Task <IResponse> DataBlockAppendAsync(IRequestContext ctx, Route route)
        {
            var tableName = GetAndValidateTableName(route);
            var table     = this.Database[tableName];

            if (table == null)
            {
                return(ArribaResponse.BadRequest("Table {0} is not loaded or does not exist", tableName));
            }

            using (ctx.Monitor(MonitorEventLevel.Information, "Import.DataBlock", type: "Table", identity: tableName))
            {
                DataBlock block = await ctx.Request.ReadBodyAsync <DataBlock>();

                table.AddOrUpdate(block, new AddOrUpdateOptions()
                {
                    AddMissingColumns = true
                });

                ImportResponse response = new ImportResponse();
                response.TableName = tableName;
                response.Columns   = block.Columns.Select((cd) => cd.Name).ToArray();
                response.RowCount  = block.RowCount;
                return(ArribaResponse.Ok(response));
            }
        }
Ejemplo n.º 5
0
        private IResponse UnloadTable(IRequestContext ctx, Route route)
        {
            var tableName = GetAndValidateTableName(route);

            this.Database.UnloadTable(tableName);
            return(ArribaResponse.Ok($"Table unloaded"));
        }
Ejemplo n.º 6
0
 private ArribaResponse Machine(IRequestContext rquest, Route data)
 {
     return(ArribaResponse.Ok(new
     {
         MachineName = Environment.MachineName,
         OsVersion = Environment.OSVersion,
         OsBitness = Environment.Is64BitOperatingSystem ? 64 : 32,
         ProcessBitness = Environment.Is64BitProcess ? 64 : 32,
         ProcessorCount = Environment.ProcessorCount
     }));
 }
Ejemplo n.º 7
0
        private ArribaResponse Memory(IRequestContext request, Route routedata)
        {
            Process currentProcess = Process.GetCurrentProcess();

            return(ArribaResponse.Ok(new Dictionary <string, object>(5)
            {
                { "totalGCBytes", GC.GetTotalMemory(false) },
                { "totalProcessBytes", currentProcess.WorkingSet64 },
                { "environmentWorkingSet", Environment.WorkingSet }
            }));
        }
Ejemplo n.º 8
0
        private IResponse GetTablePermissions(IRequestContext request, Route route)
        {
            string tableName = GetAndValidateTableName(route);

            if (!this.Database.TableExists(tableName))
            {
                return(ArribaResponse.NotFound("Table not found to return security for."));
            }

            var security = this.Database.Security(tableName);

            return(ArribaResponse.Ok(security));
        }
Ejemplo n.º 9
0
        private IResponse GetTableInformation(IRequestContext ctx, Route route)
        {
            var tableName = GetAndValidateTableName(route);

            if (!this.Database.TableExists(tableName))
            {
                return(ArribaResponse.NotFound());
            }

            TableInformation ti = GetTableBasics(tableName, ctx);

            return(ArribaResponse.Ok(ti));
        }
Ejemplo n.º 10
0
        private IResponse CsvAppend(IRequestContext ctx, Route route)
        {
            var content = ctx.Request.Headers["Content-Type"];

            if (String.IsNullOrEmpty(content) || !String.Equals(content, "text/csv", StringComparison.OrdinalIgnoreCase))
            {
                return(ArribaResponse.BadRequest("Content-Type of {0} was not expected", content));
            }
            else if (!ctx.Request.HasBody)
            {
                return(ArribaResponse.BadRequest("Empty request body"));
            }

            var tableName = GetAndValidateTableName(route);
            var table     = this.Database[tableName];

            if (table == null)
            {
                return(ArribaResponse.BadRequest("Table {0} is not loaded or does not exist", tableName));
            }

            var response = new ImportResponse();

            response.TableName = tableName;

            var config = new CsvReaderSettings()
            {
                DisposeStream = true, HasHeaders = true
            };

            var detail = new
            {
                RequestSize = ctx.Request.Headers["Content-Length"]
            };

            using (ctx.Monitor(MonitorEventLevel.Information, "Import.Csv", type: "Table", identity: tableName, detail: detail))
            {
                using (CsvReader reader = new CsvReader(ctx.Request.InputStream, config))
                {
                    response.Columns = reader.ColumnNames;

                    foreach (var blockBatch in reader.ReadAsDataBlockBatch(BatchSize))
                    {
                        response.RowCount += blockBatch.RowCount;
                        table.AddOrUpdate(blockBatch);
                    }
                }
            }

            return(ArribaResponse.Created(response));
        }
Ejemplo n.º 11
0
        private IResponse GetAllBasics(IRequestContext ctx, Route route)
        {
            Dictionary <string, TableInformation> allBasics = new Dictionary <string, TableInformation>();

            foreach (string tableName in this.Database.TableNames)
            {
                if (HasTableAccess(tableName, ctx.Request.User, PermissionScope.Reader))
                {
                    allBasics[tableName] = GetTableBasics(tableName, ctx);
                }
            }

            return(ArribaResponse.Ok(allBasics));
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Reload the specified table.
        /// </summary>
        private IResponse Reload(IRequestContext request, Route route)
        {
            string tableName = GetAndValidateTableName(route);

            if (!this.Database.TableExists(tableName))
            {
                return(ArribaResponse.NotFound("Table not found to reload"));
            }

            using (request.Monitor(MonitorEventLevel.Information, "Reload", type: "Table", identity: tableName))
            {
                this.Database.ReloadTable(tableName);
                return(ArribaResponse.Ok("Reloaded"));
            }
        }
Ejemplo n.º 13
0
        private IResponse Drop(IRequestContext ctx, Route route)
        {
            var tableName = GetAndValidateTableName(route);

            if (!this.Database.TableExists(tableName))
            {
                return(ArribaResponse.NotFound());
            }

            using (ctx.Monitor(MonitorEventLevel.Information, "Drop", type: "Table", identity: tableName))
            {
                this.Database.DropTable(tableName);
                return(ArribaResponse.Ok("Table deleted"));
            }
        }
Ejemplo n.º 14
0
        private async Task <IResponse> SetTablePermissions(IRequestContext request, Route route)
        {
            SecurityPermissions security = await request.Request.ReadBodyAsync <SecurityPermissions>();

            string tableName = GetAndValidateTableName(route);

            if (!this.Database.TableExists(tableName))
            {
                return(ArribaResponse.NotFound("Table doesn't exist to update security for."));
            }

            // Reset table permissions and save them
            this.Database.SetSecurity(tableName, security);
            this.Database.SaveSecurity(tableName);

            return(ArribaResponse.Ok("Security Updated"));
        }
Ejemplo n.º 15
0
        private IResponse DeleteRows(IRequestContext ctx, Route route)
        {
            string      tableName = GetAndValidateTableName(route);
            IExpression query     = SelectQuery.ParseWhere(ctx.Request.ResourceParameters["q"]);

            // Run server correctors
            query = this.CurrentCorrectors(ctx).Correct(query);

            if (!this.Database.TableExists(tableName))
            {
                return(ArribaResponse.NotFound());
            }

            Table        table  = this.Database[tableName];
            DeleteResult result = table.Delete(query);

            return(ArribaResponse.Ok(result.Count));
        }
        private IResponse CsvSample(IRequestContext ctx, Route route)
        {
            if (!ctx.Request.HasBody)
            {
                return(ArribaResponse.BadRequest("Empty request body"));
            }

            SampleResult result = new SampleResult();

            var config = new CsvReaderSettings()
            {
                DisposeStream = true, HasHeaders = true
            };

            using (CsvReader reader = new CsvReader(ctx.Request.InputStream, config))
            {
                // Read the CSV fragment into a DataBlock
                DataBlock block = reader.ReadAsDataBlockBatch(10000, true).FirstOrDefault();

                if (block == null)
                {
                    return(ArribaResponse.BadRequest("No result content found."));
                }

                // Count the rows actually returned
                result.RowCount = block.RowCount + 1;

                // Insert only the first 100 rows and not the last (partial) row
                block.SetRowCount(Math.Min(block.RowCount - 1, 100));

                // Build a table with the sample
                Table sample = new Table("Sample", 100);
                sample.AddOrUpdate(block, new AddOrUpdateOptions()
                {
                    AddMissingColumns = true
                });

                // Return the created columns in the order they appeared in the CSV
                result.Columns = sample.ColumnDetails.OrderBy((cd) => block.IndexOfColumn(cd.Name)).ToList();

                // Return the columns and row count from the sample
                return(ArribaResponse.Ok(result));
            }
        }
        private IResponse CsvAppend(IRequestContext ctx, Route route)
        {
            if (!ctx.Request.HasBody)
            {
                return(ArribaResponse.BadRequest("Empty request body"));
            }

            var tableName = GetAndValidateTableName(route);
            var table     = this.Database[tableName];

            if (table == null)
            {
                return(ArribaResponse.BadRequest("Table {0} is not loaded or does not exist", tableName));
            }

            var response = new ImportResponse();

            response.TableName = tableName;

            var config = new CsvReaderSettings()
            {
                DisposeStream = true, HasHeaders = true
            };

            using (ctx.Monitor(MonitorEventLevel.Information, "Import.Csv", type: "Table", identity: tableName))
            {
                using (CsvReader reader = new CsvReader(ctx.Request.InputStream, config))
                {
                    response.Columns = reader.ColumnNames;

                    foreach (var blockBatch in reader.ReadAsDataBlockBatch(BatchSize))
                    {
                        response.RowCount += blockBatch.RowCount;
                        table.AddOrUpdate(blockBatch, new AddOrUpdateOptions()
                        {
                            AddMissingColumns = true
                        });
                    }
                }
            }

            return(ArribaResponse.Ok(response));
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Add requested column(s) to the specified table.
        /// </summary>
        private async Task <IResponse> AddColumns(IRequestContext request, Route route)
        {
            string tableName = GetAndValidateTableName(route);

            using (request.Monitor(MonitorEventLevel.Information, "AddColumn", type: "Table", identity: tableName))
            {
                if (!Database.TableExists(tableName))
                {
                    return(ArribaResponse.NotFound("Table not found to Add Columns to."));
                }

                Table table = this.Database[tableName];

                List <ColumnDetails> columns = await request.Request.ReadBodyAsync <List <ColumnDetails> >();

                table.AddColumns(columns);

                return(ArribaResponse.Ok("Added"));
            }
        }
Ejemplo n.º 19
0
        private async Task <IResponse> CreateNew(IRequestContext request, Route routeData)
        {
            CreateTableRequest createTable = await request.Request.ReadBodyAsync <CreateTableRequest>();

            if (createTable == null)
            {
                return(ArribaResponse.BadRequest("Invalid body"));
            }

            // Does the table already exist?
            if (this.Database.TableExists(createTable.TableName))
            {
                return(ArribaResponse.BadRequest("Table already exists"));
            }

            using (request.Monitor(MonitorEventLevel.Information, "Create", type: "Table", identity: createTable.TableName, detail: createTable))
            {
                var table = this.Database.AddTable(createTable.TableName, createTable.ItemCountLimit);

                // Add columns from request
                table.AddColumns(createTable.Columns);

                // Include permissions from request
                if (createTable.Permissions != null)
                {
                    // Ensure the creating user is always an owner
                    createTable.Permissions.Grant(IdentityScope.User, request.Request.User.Identity.Name, PermissionScope.Owner);

                    this.Database.SetSecurity(createTable.TableName, createTable.Permissions);
                }

                // Save, so that table existence, column definitions, and permissions are saved
                table.Save();
                this.Database.SaveSecurity(createTable.TableName);
            }

            return(ArribaResponse.Ok(null));
        }
Ejemplo n.º 20
0
        private async Task <IResponse> JSONArrayAppendAsync(IRequestContext ctx, Route route)
        {
            var content = ctx.Request.Headers["Content-Type"];

            if (String.IsNullOrEmpty(content) || !String.Equals(content, "application/json", StringComparison.OrdinalIgnoreCase))
            {
                return(ArribaResponse.BadRequest("Content-Type of {0} was not expected", content));
            }
            else if (!ctx.Request.HasBody)
            {
                return(ArribaResponse.BadRequest("Empty request body"));
            }

            var tableName = GetAndValidateTableName(route);
            var table     = this.Database[tableName];

            if (table == null)
            {
                return(ArribaResponse.BadRequest("Table {0} is not loaded or does not exist", tableName));
            }

            var rows = await ctx.Request.ReadBodyAsync <List <Dictionary <string, object> > >();

            var detail = new
            {
                RequestSize = ctx.Request.Headers["Content-Length"],
                RowCount    = rows.Count
            };

            using (ctx.Monitor(MonitorEventLevel.Information, "Import.JsonObjectArray", type: "Table", identity: tableName, detail: detail))
            {
                // Read column names from JSON
                var columnDetails = new Dictionary <string, ColumnDetails>();
                foreach (var row in rows)
                {
                    foreach (var property in row)
                    {
                        if (property.Value != null && !columnDetails.ContainsKey(property.Key))
                        {
                            var colDetail = new ColumnDetails(property.Key);
                            columnDetails.Add(property.Key, colDetail);
                        }
                    }
                }

                var columns = columnDetails.Values.ToArray();

                // Insert the data in batches
                var block = new DataBlock(columns, BatchSize);
                for (int batchOffset = 0; batchOffset < rows.Count; batchOffset += BatchSize)
                {
                    int rowsLeft    = rows.Count - batchOffset;
                    int rowsInBatch = BatchSize;

                    if (rowsLeft < BatchSize)
                    {
                        block       = new DataBlock(columns, rowsLeft);
                        rowsInBatch = rowsLeft;
                    }

                    for (int blockRowIndex = 0; blockRowIndex < rowsInBatch; ++blockRowIndex)
                    {
                        int sourceRowIndex = blockRowIndex + batchOffset;

                        for (int columnIndex = 0; columnIndex < columns.Length; columnIndex++)
                        {
                            object value = null;

                            if (rows[sourceRowIndex].TryGetValue(columns[columnIndex].Name, out value))
                            {
                                block[blockRowIndex, columnIndex] = value;
                            }
                        }
                    }

                    table.AddOrUpdate(block);
                }

                using (ctx.Monitor(MonitorEventLevel.Verbose, "table.save"))
                {
                    table.Save();
                }

                return(ArribaResponse.Created(new ImportResponse
                {
                    TableName = table.Name,
                    RowCount = rows.Count(),
                    Columns = columns.Select((cd) => cd.Name).ToArray()
                }));
            }
        }
Ejemplo n.º 21
0
 private IResponse UnloadAll(IRequestContext ctx, Route route)
 {
     this.Database.UnloadAll();
     return(ArribaResponse.Ok("All Tables unloaded"));
 }
Ejemplo n.º 22
0
 private IResponse GetTables(IRequestContext ctx, Route route)
 {
     return(ArribaResponse.Ok(this.Database.TableNames));
 }